Index: libspi/collection.c
===================================================================
--- libspi/collection.c	(revision 949)
+++ libspi/collection.c	(working copy)
@@ -3,6 +3,7 @@
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
  * Copyright 2007 IBM Corp.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -23,57 +24,51 @@
 /* collection.c: implements the Collection interface */
 
 #include <config.h>
+#include <glib.h>
 #include <stdio.h>
 #include <bonobo/bonobo-exception.h>
+#include <libspi/accessible.h>
 #include <libspi/collection.h>
 #include <libspi/matchrule.h> 
+#include <libspi/stateset.h>
 #include <libspi/spi-private.h>
 
-typedef struct _MatchRulePrivate MatchRulePrivate;
+SpiCollection *
+spi_collection_interface_new (AtkObject *obj)
+{
 
-struct _MatchRulePrivate {
+     SpiCollection *new_collection = g_object_new (SPI_COLLECTION_TYPE, NULL);
+     spi_base_construct (SPI_BASE (new_collection), G_OBJECT (obj));
 
-     Accessibility_StateSet states;
-     Accessibility_Collection_MatchType statematchtype;
-     Accessibility_AttributeSet  *attributes;
-     Accessibility_Collection_MatchType attributematchtype;
-     Accessibility_RoleSet *roles;
-     Accessibility_Collection_MatchType rolematchtype;
-     CORBA_char *interfaces;
-     Accessibility_Collection_MatchType interfacematchtype;
-     gboolean invert;
+     return  new_collection;
 
-};
+}
 
-#define MATCH_RULE_PRIVATE(o)\
-     G_TYPE_INSTANCE_GET_PRIVATE((o), SPI_MATCHRULE_TYPE, MatchRulePrivate)
 
+static AtkObject *
+get_atkobject_from_servant (PortableServer_Servant servant){
 
-SpiCollection *
-spi_collection_interface_new ()
-{
+     SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
 
-     SpiCollection *new_collection = g_object_new (SPI_COLLECTION_TYPE, NULL);
-
-     spi_base_construct_default (SPI_BASE (new_collection));
-
-     return new_collection;
-
+  g_return_val_if_fail (object, NULL);
+  g_return_val_if_fail (ATK_IS_OBJECT (object->gobj), NULL);
+  
+  return ATK_OBJECT (object->gobj);
 }
 
-/*
 static SpiCollection *
 get_collection_from_servant (PortableServer_Servant servant)
 {
      SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+     
+     g_return_val_if_fail (object, NULL);
+     g_return_val_if_fail (IS_COLLECTION (object), NULL);
 
-     g_return_val_if_fail (object, NULL);
-     
-     return SPI_COLLECTION (object->gobj);
+     return SPI_COLLECTION (object);
 				
 }
-*/
 
+
 static Accessibility_MatchRule 
 impl_createMatchRule (PortableServer_Servant servant,
 		      const Accessibility_StateSet states,
@@ -90,13 +85,28 @@
      Accessibility_MatchRule  retval = NULL;
 
      SpiMatchrule *matchrule = spi_matchrule_interface_new ();
-     MatchRulePrivate *mrp   = MATCH_RULE_PRIVATE (matchrule);
-     int i;
+     MatchRulePrivate *mrp   = get_collection_from_servant (servant)->_mrp;     
+     Accessibility_StateSet ss = CORBA_Object_duplicate (states, ev);
+     gint i;
 
-     mrp->states  = states;
+
+     if (mrp != NULL){
+       CORBA_free (mrp->attributes);
+       CORBA_free (mrp->roles);
+       CORBA_free (mrp->interfaces);
+
+       g_free (mrp);
+     }
+     
+     get_collection_from_servant (servant)->_mrp  = g_new (MatchRulePrivate, 1);
+     mrp   = get_collection_from_servant (servant)->_mrp;
+
+     /* states */
+
+     mrp->states  = ss;
      mrp->statematchtype = statematchtype;
 
-/* attributes */
+     /* attributes */
 
      mrp->attributes = CORBA_sequence_CORBA_string__alloc ();
      mrp->attributes->_maximum = attributes->_maximum;
@@ -109,7 +119,7 @@
      CORBA_sequence_set_release (mrp->attributes, TRUE);
      mrp->attributematchtype = attributematchtype;
 
-/* roles */
+     /* roles */
 
      mrp->roles = Accessibility_RoleSet__alloc ();
      mrp->roles->_maximum = roles->_maximum;
@@ -122,13 +132,13 @@
      CORBA_sequence_set_release (mrp->roles, TRUE);
      mrp->rolematchtype = rolematchtype;
 
-/* interfaces */
+     /* interfaces */
      
      mrp->interfaces = CORBA_string_dup (interfaces);
      mrp->interfacematchtype = interfacematchtype;
 
      mrp->invert = invert;
-     
+
      retval = CORBA_Object_duplicate (BONOBO_OBJREF (matchrule), ev);
 
      return retval;
@@ -140,44 +150,632 @@
 				CORBA_Environment *ev){
 
      SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
-     SpiMatchrule *spimatchrule;
+     SpiCollection *spimatchrule;
 
      MatchRulePrivate *mrp;  
 
-     spimatchrule = SPI_MATCHRULE (object->gobj);
-     mrp =  MATCH_RULE_PRIVATE (spimatchrule);;
+     spimatchrule = SPI_COLLECTION (object);
+     mrp =  spimatchrule->_mrp;
      
      CORBA_free (mrp->attributes);
      CORBA_free (mrp->roles);
-     CORBA_free (mrp->interfaces);     
+     CORBA_free (mrp->interfaces);
+
+     g_free (mrp);
+
+}
+
+
+
+static gboolean
+child_interface_p (Accessibility_Accessible child, gchar *repo_id, CORBA_Environment *ev) {
+          
+     CORBA_Object retval;
      
-     g_free (spimatchrule);
+     retval = Bonobo_Unknown_queryInterface (child, repo_id, ev);
+     
+     return (retval != CORBA_OBJECT_NIL)? TRUE : FALSE;
 
 }
+
+#define child_collection_p(ch,ev) (child_interface_p (ch,"IDL:Accessibility/Collection:1.0", ev))
+
+static gboolean
+match_states_all_p (Accessibility_Accessible child, Accessibility_StateSet set,  CORBA_Environment *ev){
+     
+
+     Accessibility_StateSet chs  ;
+     Accessibility_StateSeq *seq = Accessibility_StateSet_getStates (set, ev); 
+     gint i;
+
+     if (seq->_length == 0 || seq == NULL)
+	  return TRUE;
+
+     chs = Accessibility_Accessible_getState (child, ev);
+     
+     
+     for (i = 0; i < seq->_length; i++)
+	  if (!Accessibility_StateSet_contains (chs, seq->_buffer [i], ev))
+	       return FALSE;
+   
+     return TRUE;
+	  
+}
+
+static gboolean
+match_states_any_p  (Accessibility_Accessible child, Accessibility_StateSet set,  CORBA_Environment *ev){
+     
+     Accessibility_StateSet chs; 
+     Accessibility_StateSeq *seq = Accessibility_StateSet_getStates (set, ev);
+     gint i;
+
+     if (seq->_length == 0 || seq == NULL)
+	  return TRUE;
+
+     chs = Accessibility_Accessible_getState (child, ev);
+
+     for (i = 0; i < seq->_length; i++)
+   	  if (Accessibility_StateSet_contains (chs, seq->_buffer [i], ev))
+	       return TRUE;
+
+     return FALSE;
+
+}
+
+static gboolean
+match_states_none_p (Accessibility_Accessible child, Accessibility_StateSet set,  CORBA_Environment *ev){
+     
+     Accessibility_StateSet chs; 
+     Accessibility_StateSeq *seq = Accessibility_StateSet_getStates (set, ev);
+     gint i;
+
+     if (seq->_length == 0)
+	  return TRUE; 
+     chs = Accessibility_Accessible_getState (child, ev);
+     
+     for (i = 0; i < seq->_length; i++)
+	  if (Accessibility_StateSet_contains (chs, seq->_buffer [i], ev))
+	       return FALSE;
+
+     return TRUE;
+
+}
+
+static gboolean
+match_states_lookup (Accessibility_Accessible child,  MatchRulePrivate *mrp, CORBA_Environment *ev){
+
+     switch (mrp->statematchtype){
+     case Accessibility_Collection_MATCH_ALL : 
+	  if (match_states_all_p (child, mrp->states, ev))
+	       return TRUE;
+	  break;
+	  
+     case  Accessibility_Collection_MATCH_ANY :
+	  if (match_states_any_p (child, mrp->states, ev))
+	       return TRUE;
+	  break;
+	  
+     case  Accessibility_Collection_MATCH_NONE :
+	  if (match_states_none_p (child, mrp->states, ev))
+	       return TRUE;
+	  break;
+
+      default : break;	  
+     }
+
+     return FALSE;    
+
+}
+
+static gboolean
+match_roles_all_p (Accessibility_Accessible child, Accessibility_RoleSet *roles,  CORBA_Environment *ev){
+
+   Accessibility_Role role; 
+
+     if (roles->_length > 1) 
+	  return FALSE;
+     else if (roles->_length == 0 || roles == NULL)
+	  return TRUE;
+
+     role  = Accessibility_Accessible_getRole (child, ev);
+
+     if (role  == roles->_buffer [0])
+	  return TRUE;
+     else 
+	  return FALSE;
+    
+}
+
+
+static gboolean
+match_roles_any_p (Accessibility_Accessible child, Accessibility_RoleSet *roles, CORBA_Environment *ev){
+
+     Accessibility_Role role; 
+     int i;
+
+     if (roles->_length == 0 || roles == NULL)
+	  return TRUE;
+
+     role =  Accessibility_Accessible_getRole (child, ev);
+
+     for (i = 0; i < roles->_length; i++)
+	  if (role  == roles->_buffer [i])
+	       return TRUE;
+
+     return FALSE;
+
+}
+
+static gboolean
+match_roles_none_p (Accessibility_Accessible child, Accessibility_RoleSet *roles,  CORBA_Environment *ev){
+
+  Accessibility_Role role ; 
+     int i;
+
+     if (roles->_length == 0 || roles == NULL)
+	  return TRUE;
+
+     role =  Accessibility_Accessible_getRole (child, ev);
+
+     for (i = 0; i < roles->_length; i++)
+	  if (role == roles->_buffer [i])
+	       return FALSE;
+
+     return TRUE;
+     
+}
+
+
+static gboolean
+match_roles_lookup (Accessibility_Accessible child,  MatchRulePrivate *mrp, CORBA_Environment *ev){
+
+      switch (mrp->rolematchtype){
+	 case Accessibility_Collection_MATCH_ALL : 
+	      if (match_roles_all_p (child, mrp->roles, ev))
+		   return TRUE;
+	      break;
+
+	 case  Accessibility_Collection_MATCH_ANY :
+	      if (match_roles_any_p (child, mrp->roles, ev))
+		   return TRUE;
+	      break;
+
+	 case  Accessibility_Collection_MATCH_NONE :
+	      if (match_roles_none_p (child, mrp->roles, ev))
+		   return TRUE;
+	      break;
+
+      default : break;
+ 
+	 }
+
+      return FALSE;
+
+}
+
+
+#define split_ifaces(ifaces) (g_strsplit (ifaces, ";", 0))
+
+static gboolean
+match_interfaces_all_p (Accessibility_Accessible obj, gchar *interfaces, CORBA_Environment *ev){
+     gchar **ifaces; 
+     gint i, length; 
+
+     if (interfaces == NULL)
+       return TRUE;
+
+     ifaces = split_ifaces (interfaces);
+     length = g_strv_length (ifaces);
+
+     for (i = 0; i < length; i++)
+       if (!child_interface_p (obj, ifaces [i], ev)){
+	    g_free (ifaces);
+	       return FALSE;
+       }
+     return TRUE;
+     
+
+}
+
+static gboolean
+match_interfaces_any_p (Accessibility_Accessible obj, gchar *interfaces, CORBA_Environment *ev){
+     gchar **ifaces; 
+     gint i, length; 
+
+     if (interfaces == NULL)
+       return TRUE;
+
+     ifaces = split_ifaces (interfaces);
+     length = g_strv_length (ifaces);
+
+     for (i = 0; i < length; i++)
+       if (child_interface_p (obj, ifaces [i], ev)){
+	        g_free (ifaces);
+		return TRUE;
+       }
+     
+     return FALSE;
+}
+
+static gboolean
+match_interfaces_none_p (Accessibility_Accessible obj, gchar *interfaces, CORBA_Environment *ev){
+
+ gchar **ifaces = split_ifaces (interfaces);
+     gint i, length = g_strv_length (ifaces);
+
+     if (length == 0)
+	  return TRUE;
+
+     for (i = 0; i < length; i++)
+	   if (child_interface_p (obj, ifaces [i], ev))
+		return FALSE;
+     
+     return TRUE;
+   
+
+}
+
+static gboolean
+match_interfaces_lookup (Accessibility_Accessible child, MatchRulePrivate *mrp, CORBA_Environment *ev){
+
+     switch (mrp->interfacematchtype){
+
+     case Accessibility_Collection_MATCH_ALL : 
+	  if (match_interfaces_all_p (child, mrp->interfaces, ev))
+	       return TRUE;
+	  break;
+	  
+     case  Accessibility_Collection_MATCH_ANY :
+	  if (match_interfaces_any_p (child, mrp->interfaces, ev))
+	       return TRUE;
+	  break;
+	  
+     case  Accessibility_Collection_MATCH_NONE :
+	  if (match_interfaces_none_p (child, mrp->interfaces, ev))
+	       return TRUE;
+	  break;
+
+      default : break;	  
+     }
+
+     return FALSE;     
+}
+
+#define split_attributes(attributes) (g_strsplit (attributes, ";", 0))
+
+static gboolean 
+match_attributes_all_p (Accessibility_Accessible child, Accessibility_AttributeSet  *attributes, CORBA_Environment *ev){
+
+     int i, k;
+     Accessibility_AttributeSet *oa ;
+     gboolean flag = FALSE;
+
+     if (attributes->_length == 0 || attributes == NULL)
+	  return TRUE;
+     
+     oa =  Accessibility_Accessible_getAttributes (child, ev);
+
+     for (i = 0; i < attributes->_length; i++){
+	  for (k = 0; k < oa->_length; k++)
+	       if (!g_ascii_strcasecmp (oa->_buffer [k], attributes->_buffer [i]))
+		    flag = TRUE;
+	       else
+		    flag = FALSE;
+	  if (!flag) 
+	       return FALSE; 
+     }
+     return TRUE;
+}
+
+static gboolean 
+match_attributes_any_p (Accessibility_Accessible child, Accessibility_AttributeSet  *attributes, CORBA_Environment *ev){
+
+     int i, k;
+
+     Accessibility_AttributeSet *oa;
+
+     if (attributes->_length == 0 || attributes == NULL)
+	  return TRUE;
+
+     oa =  Accessibility_Accessible_getAttributes (child, ev);
+
+     for (i = 0; i < attributes->_length; i++)
+	  for (k = 0; k < oa->_length; k++)
+	       if (!g_ascii_strcasecmp (oa->_buffer [k], attributes->_buffer[i]))
+		    return TRUE;
+     return FALSE;
+}
+
+
+
+static gboolean 
+match_attributes_none_p (Accessibility_Accessible child, Accessibility_AttributeSet  *attributes, CORBA_Environment *ev){
+
+     int i, k;
+     Accessibility_AttributeSet *oa;
+     gboolean flag = FALSE;
+     
+     if (attributes->_length == 0 || attributes == NULL)
+	  return TRUE;
+
+     oa =  Accessibility_Accessible_getAttributes (child, ev);
+
+     for (i = 0; i < attributes->_length; i++){
+	  for (k = 0; k < oa->_length; k++)
+	       if (!g_ascii_strcasecmp (oa->_buffer [k], attributes->_buffer [i]))
+		    flag = FALSE;
+	       else
+		    flag = TRUE;
+	  if (flag) 
+	       return TRUE; 
+     }
+     return FALSE;
+}
+
+
+
+
+static gboolean
+match_attributes_lookup (Accessibility_Accessible child, MatchRulePrivate *mrp, CORBA_Environment *ev){
+
+     switch (mrp->attributematchtype){
+
+	  case Accessibility_Collection_MATCH_ALL : 
+	  if (match_attributes_all_p (child, mrp->attributes, ev))
+	       return TRUE;
+	  break;
+	  
+     case  Accessibility_Collection_MATCH_ANY :
+	  if (match_attributes_any_p (child, mrp->attributes, ev))
+	       return TRUE;
+	  break;
+	  
+     case  Accessibility_Collection_MATCH_NONE :
+	  if (match_attributes_none_p (child, mrp->attributes, ev))
+	       return TRUE;
+	  break;
+
+      default : break;	  
+     }
+
+     return FALSE;   
+
+
+
+}
+
+static gboolean
+traverse_p (Accessibility_Accessible child, 
+            const CORBA_boolean traverse,
+	    CORBA_Environment *ev){
+
+  if (traverse)
+    return TRUE;
+  else return !child_collection_p (child, ev);
+        
+}
+
+static int 
+sort_order_canonical (MatchRulePrivate *mrp, GList *ls, 		      
+		      gint kount, gint max,
+		      Accessibility_Accessible obj, glong index, gboolean flag, 
+		      Accessibility_Accessible pobj, CORBA_boolean recurse, 
+		      CORBA_boolean traverse, CORBA_Environment *ev){
+
+     gint i = index;
+     glong acount  = Accessibility_Accessible__get_childCount (obj, ev);
+     gboolean prev = pobj? TRUE : FALSE;
+   
+     for (; i < acount && (max == 0 || kount < max); i++){
+	  Accessibility_Accessible child = Accessibility_Accessible_getChildAtIndex (obj, i, ev);
+
+	          
+	  if (prev && CORBA_Object_is_equivalent (child, pobj, ev)){
+
+	    return kount;           
+
+	  }
+	 
+	  if (flag  && match_interfaces_lookup (child, mrp, ev) && match_states_lookup (child, mrp, ev)     
+                    && match_roles_lookup (child, mrp, ev)  
+		    && match_attributes_lookup (child, mrp, ev)
+	      	    ){
+	   
+	    ls = g_list_append (ls, child);
+	    
+	    kount++;
+	  }
+	    
+	  if (!flag)
+	       flag = TRUE;
+
+	 
+	  if (recurse && traverse_p (child, traverse, ev))
+	    kount = sort_order_canonical (mrp, ls,  kount, max, child, 0, TRUE, pobj, recurse, traverse, ev);  
+     }
+     return kount;
+} 
+
+static int
+query_exec (MatchRulePrivate *mrp,  Accessibility_Collection_SortOrder sortby, 
+	    GList *ls, gint kount, gint max, 
+	    Accessibility_Accessible obj, glong index, 
+	    gboolean flag, 
+	    Accessibility_Accessible pobj,
+	    CORBA_boolean recurse, CORBA_boolean traverse,
+            CORBA_Environment *ev){
+     switch (sortby) {
+     case Accessibility_Collection_SORT_ORDER_CANONICAL :  kount = sort_order_canonical  (mrp, ls, 0, max, obj, index, flag, pobj, recurse, traverse, ev); 
+       break;
+     case Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL :
+       kount = sort_order_canonical  (mrp, ls, 0, max, obj, index, flag, pobj, recurse, traverse, ev);    
+	   break;
+       
+     default: kount = 0; g_warning ("Sort method not implemented yet"); break; 
+     }
+     
+     return kount;
+
+}
+
+
+static Accessibility_AccessibleSet *
+_accessible_list_to_set (GList *ls, gint kount){
+    Accessibility_AccessibleSet *retval;
+    gint i;
+   
+     retval = Accessibility_AccessibleSet__alloc ();
+     retval->_maximum = kount; 
+     retval->_length = kount; 
+     retval->_buffer = Accessibility_AccessibleSet_allocbuf (kount);
+
+     for (i=0; i < kount; i++){
+       retval->_buffer [i] = ls->data;
+       ls = g_list_next (ls);
+     }
+     
+     CORBA_sequence_set_release (retval, TRUE);
+     
+     return retval;
+}
+
+static Accessibility_AccessibleSet *
+impl_getMatchesFrom (PortableServer_Servant servant,
+		      const Accessibility_Accessible current_object,
+		      const Accessibility_MatchRule rule,
+		      const Accessibility_Collection_SortOrder sortby,
+		      const CORBA_boolean restrict,
+		      CORBA_long  count,
+		      const CORBA_boolean traverse,
+		      CORBA_Environment *ev){
+    
+     GList *ls = NULL;
+     Accessibility_Accessible parent; 
+     MatchRulePrivate *mrp;
+     glong index = Accessibility_Accessible_getIndexInParent (current_object, ev);
+     gint kount = 0;
+
+     ls = g_list_append (ls, current_object);
+     mrp =  get_collection_from_servant (servant)->_mrp;;
+          
+     if (!restrict){
+          parent = Accessibility_Accessible__get_parent (current_object, ev);
+	  kount = query_exec (mrp,  sortby, ls, 0, count, parent, index, FALSE, CORBA_OBJECT_NIL, TRUE, traverse, ev);
+
+     }
+     else 
+	  kount = query_exec (mrp,  sortby, ls, 0,count,  current_object, 0, FALSE, CORBA_OBJECT_NIL, TRUE, traverse, ev);
+
+
+     ls = g_list_next (ls); 
+
+     if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+       ls = g_list_reverse (ls);
+ 
+     return  _accessible_list_to_set (ls, kount);
+}
+
+
+static Accessibility_AccessibleSet *
+impl_getMatchesTo (PortableServer_Servant servant,
+		      const Accessibility_Accessible current_object,
+		      const Accessibility_MatchRule rule,
+		      const Accessibility_Collection_SortOrder sortby,
+		      const CORBA_boolean restrict, 
+		      CORBA_long  count,
+		      const CORBA_boolean traverse,
+		      CORBA_Environment *ev){
+
+
+  GList *ls = NULL;
+  AtkObject *aobj;
+  Accessibility_Accessible obj;
+  MatchRulePrivate *mrp;
+   gint kount = 0;
+
+
+  ls = g_list_append (ls, current_object); 
+  mrp =  get_collection_from_servant (servant)->_mrp;
+  
+  
+  if (restrict){
+    obj = Accessibility_Accessible__get_parent (current_object, ev);
+    kount =  query_exec (mrp,  sortby, ls, 0, count,  obj, 0, TRUE, current_object, TRUE, traverse, ev);
+  }
+  else{
+    aobj = get_atkobject_from_servant (servant);
+    obj = spi_accessible_new_return (aobj, FALSE, ev);
+    kount = query_exec (mrp,  sortby, ls, 0, count, obj, 0, TRUE, current_object, TRUE, traverse, ev); 
+
+  }
+
+  ls = g_list_next (ls); 
+   
+  if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+    ls = g_list_reverse (ls);
+ 
+  return  _accessible_list_to_set (ls, kount);
+  
+}
+
+
+
+static Accessibility_AccessibleSet *
+impl_getMatches (PortableServer_Servant servant,
+		 const Accessibility_MatchRule rule,
+		 const Accessibility_Collection_SortOrder sortby,
+		 CORBA_long  count,
+                 const CORBA_boolean traverse,
+		 CORBA_Environment *ev){
+     GList *ls = NULL;
+     AtkObject *aobj = get_atkobject_from_servant (servant);
+     Accessibility_Accessible obj;
+     MatchRulePrivate *mrp;
+     gint kount = 0;
+    
+     obj = spi_accessible_new_return (aobj, FALSE, ev);
+     ls = g_list_prepend (ls, obj); 
+     mrp =  get_collection_from_servant (servant)->_mrp;
+     
+     kount = query_exec (mrp,  sortby, ls, 0, count, obj, 0, TRUE, CORBA_OBJECT_NIL, TRUE, traverse, ev); 
+
+     ls = g_list_next (ls); 
+    
+     if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+       ls = g_list_reverse (ls);
+
+     return  _accessible_list_to_set (ls, kount);
+}
+
 static void
 spi_collection_class_init (SpiCollectionClass *klass)
 {
 
     POA_Accessibility_Collection__epv *epv  = &klass->epv;
 
-    /*    epv->isAncestorOf = impl_isAncestorOf; */
+    /*    
+      epv->isAncestorOf = impl_isAncestorOf; 
+    */
+
+    epv->createMatchRule = impl_createMatchRule;
+    epv->freeMatchRule   = impl_freeMatchRule;
+    epv->getMatches      = impl_getMatches;
+    epv->getMatchesTo    = impl_getMatchesTo;
+    epv->getMatchesFrom  = impl_getMatchesFrom;
     
-   epv->createMatchRule =  impl_createMatchRule;
-   epv->freeMatchRule = impl_freeMatchRule;
-   
-   /*
-     epv->getChildren = impl_getChildren;
-     epv->getPreviousChildren = impl_getPreviousChildren;
-     epv->getNextChildren = impl_getNextChildren;
-     epv->getActiveDescendant = impl_getActiveDescendant;
-   */
 
-   g_type_class_add_private (klass, sizeof (MatchRulePrivate));
+    /*
+      epv->getActiveDescendant = impl_getActiveDescendant;
+    */
+
 }
 
 static void
 spi_collection_init (SpiCollection *collection)
 {
+
+  //collection->_mrp = g_new (MatchRulePrivate, 1);
+
 }
 
 BONOBO_TYPE_FUNC_FULL (SpiCollection,
Index: libspi/accessible.c
===================================================================
--- libspi/accessible.c	(revision 949)
+++ libspi/accessible.c	(working copy)
@@ -2,6 +2,8 @@
  * AT-SPI - Assistive Technology Service Provider Interface
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
+ * Copyright 2007 IBM Corp 
  * Copyright 2001, 2002 Sun Microsystems Inc.,
  * Copyright 2001, 2002 Ximian, Inc.
  *
@@ -631,10 +633,16 @@
         bonobo_object_add_interface (bonobo_object (retval),
 				     BONOBO_OBJECT (spi_streamable_interface_new (o)));
       }
-    if (ATK_IS_DOCUMENT (o))
+    if (ATK_IS_DOCUMENT (o)) /* We add collection interface to document */
       {
-	bonobo_object_add_interface (bonobo_object (retval),
-	                             BONOBO_OBJECT (spi_document_interface_new (o)));
+
+	   
+	 SpiDocument *doc = spi_document_interface_new (o);
+	 bonobo_object_add_interface (BONOBO_OBJECT (doc), 
+				      BONOBO_OBJECT (spi_collection_interface_new (o)));
+
+	 bonobo_object_add_interface (bonobo_object (retval),
+					BONOBO_OBJECT (doc));
       }
     if (ATK_IS_HYPERLINK_IMPL (o))
       {
Index: libspi/collection.h
===================================================================
--- libspi/collection.h	(revision 949)
+++ libspi/collection.h	(working copy)
@@ -30,16 +30,32 @@
 #define SPI_COLLECTION_TYPE         (spi_collection_get_type ())
 #define SPI_COLLECTION(obj)         (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_COLLECTION_TYPE, SpiCollection))
 #define SPI_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPI_COLLECTION_TYPE, SpiCollectionClass))
-#define IS_COLLECTION(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj, SPI_COLLECTION_TYPE))
+#define IS_COLLECTION(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_COLLECTION_TYPE))
 #define IS_COLLECTION_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_COLLECTION_TYPE))
 
+typedef struct _MatchRulePrivate MatchRulePrivate;
+
+struct _MatchRulePrivate {
+
+     Accessibility_StateSet states; 
+     Accessibility_Collection_MatchType statematchtype;
+     Accessibility_AttributeSet  *attributes;
+     Accessibility_Collection_MatchType attributematchtype;
+     Accessibility_RoleSet *roles;
+     Accessibility_Collection_MatchType rolematchtype;
+     CORBA_char *interfaces;
+     Accessibility_Collection_MatchType interfacematchtype;
+     gboolean invert;
+
+};
+
 typedef struct _SpiCollection SpiCollection;
 typedef struct _SpiCollectionClass SpiCollectionClass;
 
 struct _SpiCollection {
   SpiBase parent;
+  MatchRulePrivate *_mrp;
 
-
 };
 
 struct _SpiCollectionClass {
@@ -51,7 +67,7 @@
 
 void         spi_collection_construct      (SpiCollection *collection);
 					    
-SpiCollection *spi_collection_interface_new  (void);
+SpiCollection *spi_collection_interface_new  (AtkObject *obj);
 
 G_END_DECLS
 
Index: idl/Accessibility_Collection.idl
===================================================================
--- idl/Accessibility_Collection.idl	(revision 949)
+++ idl/Accessibility_Collection.idl	(working copy)
@@ -24,14 +24,10 @@
 #define __ACCESSIBILITY_COLLECTION_DEFINED__
  
 module Accessibility {
+  
 
-struct AccessibleSetEntry {
-         Accessible accessible;
-         string     name;
-         Role       role;
-};
+  typedef sequence<Accessible> AccessibleSet;
 
-typedef sequence<AccessibleSetEntry> AccessibleSet;
  
      interface MatchRule {
      };
@@ -74,23 +70,25 @@
 
 	void             freeMatchRule (in MatchRule rule);
 
-	AccessibleSet getChildren (in MatchRule rule,
-                                   in SortOrder sortby,
-				   in boolean recurse,
-                                   inout long count); /* inOut not accepted */
+	AccessibleSet getMatches (in MatchRule rule,
+                                  in SortOrder sortby,
+				  in long count,
+                                  in boolean traverse); 
 
-	AccessibleSet getPreviousChildren (in Accessible current_object,
+	AccessibleSet getMatchesTo (in Accessible current_object,
                                            in MatchRule rule, 
                                            in SortOrder sortby, 
                                            in boolean recurse,
-                                           inout long count);
+                                           in long count,
+                                           in boolean traverse);
 
 
-        AccessibleSet getNextChildren (in Accessible current_object,
+        AccessibleSet getMatchesFrom (in Accessible current_object,
 				       in MatchRule rule, 
                                        in SortOrder sortby, 
-                                       in boolean recurse,
-                                       inout long count);
+                                       in boolean restrict,
+				       in long count,
+                                       in boolean traverse);
 
         Accessible getActiveDescendant ();
