Index: configure.in
===================================================================
--- configure.in	(revision 326)
+++ configure.in	(working copy)
@@ -114,6 +114,7 @@
 			   have_libxml2=no)
 AC_SUBST(LIBXML2_VERSION)
 AC_SUBST(CROCO_HAVE_LIBXML2)
+AM_CONDITIONAL([CROCO_HAVE_LIBXML2], [test "$have_libxml2" = "yes"])
 
 CROCO_LIB=libcroco-$LIBCROCO_MAJOR_VERSION.$LIBCROCO_MINOR_VERSION.la
 AC_SUBST(CROCO_LIB)
@@ -138,7 +139,7 @@
         -Wparentheses -Wpointer-arith -Wcast-align \
         -Wwrite-strings -Waggregate-return -Wstrict-prototypes \
         -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls"
-	
+
 fi
 
 dnl
Index: src/cr-xml-sel-eng.h
===================================================================
--- src/cr-xml-sel-eng.h	(revision 0)
+++ src/cr-xml-sel-eng.h	(revision 0)
@@ -0,0 +1,81 @@
+/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
+
+/*
+ * This file is part of The Croco Library
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2.1 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ * Author: Robert Staudinger
+ * Based on: cr-sel-eng.h
+ * See COPYRIGHTS file for copyrights information.
+ */
+
+#ifndef __CR_XML_SEL_ENG_H__
+#define __CR_XML_SEL_ENG_H__
+
+#include <libxml/tree.h>
+#include "cr-sel-eng.h"
+
+/**
+ *@file:
+ *The declaration of the  #CRSelEng class.
+ *The #CRSelEng is actually the "Selection Engine"
+ *class.
+ */
+
+G_BEGIN_DECLS
+
+/* TODO Rob what to do about this?
+typedef gboolean (*CRPseudoClassSelectorHandler) (CRSelEng* a_this,
+                                                  CRAdditionalSel *a_add_sel,
+                                                  CRNode const *a_node) ;
+
+enum CRStatus cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng *a_this,
+                                                            guchar *a_pseudo_class_sel_name,
+                                                            enum CRPseudoType a_pseudo_class_type,
+                                                            CRPseudoClassSelectorHandler a_handler) ;
+
+enum CRStatus cr_sel_eng_get_pseudo_class_selector_handler (CRSelEng *a_this,
+                                                            guchar *a_pseudo_class_sel_name,
+                                                            enum CRPseudoType a_pseudo_class_type,
+                                                            CRPseudoClassSelectorHandler *a_handler) ;
+*/
+
+enum CRStatus cr_xml_sel_eng_matches_node (CRSelEng *a_this,
+                                           CRSimpleSel *a_sel,
+                                           xmlNode *a_node,
+                                           gboolean *a_result) ;
+
+enum CRStatus cr_xml_sel_eng_get_matched_rulesets (CRSelEng *a_this,
+                                                   CRStyleSheet *a_sheet,
+                                                   xmlNode *a_node,
+                                                   CRStatement ***a_rulesets,
+                                                   gulong *a_len) ;
+
+enum CRStatus cr_xml_sel_eng_get_matched_properties_from_cascade  (CRSelEng *a_this,
+                                                                   CRCascade *a_cascade,
+                                                                   xmlNode *a_node,
+                                                                   CRPropList **a_props) ;
+
+enum CRStatus cr_xml_sel_eng_get_matched_style (CRSelEng *a_this,
+                                                CRCascade *a_cascade,
+                                                xmlNode *a_node,
+                                                CRStyle *a_parent_style,
+                                                CRStyle **a_style,
+                                                gboolean a_set_props_to_initial_values) ;
+
+G_END_DECLS
+
+#endif/*__CR_XML_SEL_ENG_H__*/
Index: src/cr-sel-eng.h
===================================================================
--- src/cr-sel-eng.h	(revision 326)
+++ src/cr-sel-eng.h	(working copy)
@@ -30,12 +30,6 @@
 #include "cr-style.h"
 #include "cr-prop-list.h"
 
-#ifdef CROCO_HAVE_LIBXML2
- #include <libxml/tree.h>
-#endif
-
-
-
 /**
  *@file:
  *The declaration of the  #CRSelEng class.
@@ -45,6 +39,27 @@
 
 G_BEGIN_DECLS
 
+typedef struct _CRNode      CRNode;
+typedef struct _CRNodeIface CRNodeIface;
+
+struct _CRNode {
+        CRNodeIface const *iface;
+};
+
+struct _CRNodeIface {
+	/* Names based on DOM. */
+	CRNode *        (*get_parent_node)      (CRNode const *);
+	CRNode *        (*get_first_child)      (CRNode const *);
+	CRNode *        (*get_next_sibling)     (CRNode const *);
+	CRNode *        (*get_previous_sibling) (CRNode const *);
+	char const *    (*get_node_name)        (CRNode const *);
+	char *          (*get_attribute)        (CRNode const *, char const *);
+	/* Additional methods for DOM emulation / CSS matching. */
+	guint           (*get_children_count)   (CRNode const *);
+	guint           (*get_index)            (CRNode const *);
+	void            (*release)              (CRNode *);
+};
+
 typedef struct _CRSelEng CRSelEng ;
 typedef struct _CRSelEngPriv CRSelEngPriv ;
 
@@ -63,11 +78,11 @@
 
 typedef gboolean (*CRPseudoClassSelectorHandler) (CRSelEng* a_this,
                                                   CRAdditionalSel *a_add_sel,
-                                                  xmlNode *a_node) ;
+                                                  CRNode const *a_node) ;
 CRSelEng * cr_sel_eng_new (void) ;
 
 enum CRStatus cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng *a_this,
-                                                            guchar *a_pseudo_class_sel_name,
+                                                            gchar const *a_pseudo_class_sel_name,
                                                             enum CRPseudoType a_pseudo_class_type,
                                                             CRPseudoClassSelectorHandler a_handler) ;
 
@@ -78,30 +93,30 @@
 enum CRStatus cr_sel_eng_unregister_all_pseudo_class_sel_handlers (CRSelEng *a_this) ;
 
 enum CRStatus cr_sel_eng_get_pseudo_class_selector_handler (CRSelEng *a_this,
-                                                            guchar *a_pseudo_class_sel_name,
+                                                            gchar const *a_pseudo_class_sel_name,
                                                             enum CRPseudoType a_pseudo_class_type,
                                                             CRPseudoClassSelectorHandler *a_handler) ;
 
-enum CRStatus cr_sel_eng_matches_node (CRSelEng *a_this, 
+enum CRStatus cr_sel_eng_matches_node (CRSelEng *a_this,
                                        CRSimpleSel *a_sel,
-                                       xmlNode *a_node, 
+                                       CRNode const *a_node,
                                        gboolean *a_result) ;
 
 enum CRStatus cr_sel_eng_get_matched_rulesets (CRSelEng *a_this,
                                                CRStyleSheet *a_sheet,
-                                               xmlNode *a_node,
+                                               CRNode const *a_node,
                                                CRStatement ***a_rulesets,
                                                gulong *a_len) ;
 
 enum CRStatus
 cr_sel_eng_get_matched_properties_from_cascade  (CRSelEng *a_this,
                                                  CRCascade *a_cascade,
-                                                 xmlNode *a_node,
+                                                 CRNode const *a_node,
                                                  CRPropList **a_props) ;
 
 enum CRStatus cr_sel_eng_get_matched_style (CRSelEng *a_this,
                                             CRCascade *a_cascade,
-                                            xmlNode *a_node,
+                                            CRNode const *a_node,
                                             CRStyle *a_parent_style,
                                             CRStyle **a_style,
                                             gboolean a_set_props_to_initial_values) ;
Index: src/libcroco.h
===================================================================
--- src/libcroco.h	(revision 326)
+++ src/libcroco.h	(working copy)
@@ -41,4 +41,8 @@
 #include "cr-style.h"
 #include "cr-string.h"
 
+#ifdef CROCO_HAVE_LIBXML2
+#include "cr-xml-sel-eng.h"
+#endif
+
 #endif /*__LIBCROCO_H__*/
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 326)
+++ src/Makefile.am	(working copy)
@@ -34,7 +34,6 @@
 cr-string.h \
 libcroco-config.h
 
-
 #the files to be compiled
 SRCS=\
 cr-utils.c \
@@ -90,6 +89,11 @@
 cr-string.c \
 cr-string.h
 
+if CROCO_HAVE_LIBXML2
+crocoinc_HEADERS += cr-xml-sel-eng.h
+SRCS += cr-xml-sel-eng.c
+endif
+
 lib_LTLIBRARIES=libcroco-0.6.la
 libcroco_0_6_la_SOURCES= $(SRCS)
 
Index: src/cr-xml-sel-eng.c
===================================================================
--- src/cr-xml-sel-eng.c	(revision 0)
+++ src/cr-xml-sel-eng.c	(revision 0)
@@ -0,0 +1,370 @@
+/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
+
+/*
+ * This file is part of The Croco Library
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2.1 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ * Author: Robert Staudinger
+ * See COPYRIGHTS file for copyrights information.
+ */
+
+#include "cr-xml-sel-eng.h"
+
+#define CR_XML_LOG(node)
+//#define CR_XML_LOG(node) \
+//                printf ("%s(%s)\n", __FUNCTION__, node ? node->name : NULL);
+
+typedef struct {
+        CRNode  base;
+        xmlNode *node;
+} CRXmlNode;
+
+static CRNodeIface const * peek_node_iface (void);
+
+static CRNode *
+cr_xml_node_new (xmlNode *node)
+{
+        CRXmlNode *self;
+
+        CR_XML_LOG (node);
+
+        if (!node)
+                return NULL;
+
+        g_return_val_if_fail (node->type == XML_ELEMENT_NODE, NULL);
+
+        self = g_new0 (CRXmlNode, 1);
+        self->base.iface = peek_node_iface ();
+        self->node = node;
+
+        return &self->base;
+}
+
+static void
+cr_xml_node_free (CRXmlNode *self)
+{
+        g_return_if_fail (self);
+
+        CR_XML_LOG (self->node);
+
+        g_free (self);
+}
+
+static CRNode *
+get_parent_node (CRNode const *node)
+{
+        CRXmlNode       *self = (CRXmlNode *) node;
+        xmlNode         *cur_node;
+
+        g_return_val_if_fail (self, NULL);
+        g_return_val_if_fail (self->node, NULL);
+
+        CR_XML_LOG (self->node);
+
+        cur_node = self->node->parent;
+        while (cur_node && cur_node->type != XML_ELEMENT_NODE) {
+                cur_node = cur_node->parent;
+        }
+
+        return cr_xml_node_new (cur_node);
+}
+
+static CRNode *
+get_first_child (CRNode const *node)
+{
+        CRXmlNode       *self = (CRXmlNode *) node;
+        xmlNode         *cur_node;
+
+        g_return_val_if_fail (self, NULL);
+        g_return_val_if_fail (self->node, NULL);
+
+        CR_XML_LOG (self->node);
+
+        cur_node = self->node->children;
+        while (cur_node && cur_node->type != XML_ELEMENT_NODE) {
+                cur_node = cur_node->next;
+        }
+
+        return cr_xml_node_new (cur_node);
+}
+
+static CRNode *
+get_next_sibling (CRNode const *node)
+{
+        CRXmlNode       *self = (CRXmlNode *) node;
+        xmlNode         *cur_node;
+
+        g_return_val_if_fail (self, NULL);
+        g_return_val_if_fail (self->node, NULL);
+
+        CR_XML_LOG (self->node);
+
+        cur_node = self->node->next;
+        while (cur_node && cur_node->type != XML_ELEMENT_NODE) {
+                cur_node = cur_node->next;
+        }
+
+        return cr_xml_node_new (cur_node);
+}
+
+static CRNode *
+get_previous_sibling (CRNode const *node)
+{
+        CRXmlNode       *self = (CRXmlNode *) node;
+        xmlNode         *cur_node;
+
+        g_return_val_if_fail (self, NULL);
+        g_return_val_if_fail (self->node, NULL);
+
+        CR_XML_LOG (self->node);
+
+        cur_node = self->node->prev;
+        while (cur_node && cur_node->type != XML_ELEMENT_NODE) {
+                cur_node = cur_node->prev;
+        }
+
+        return cr_xml_node_new (cur_node);
+}
+
+static char const *
+get_node_name (CRNode const *node)
+{
+        CRXmlNode       *self = (CRXmlNode *) node;
+
+        g_return_val_if_fail (self, NULL);
+        g_return_val_if_fail (self->node, NULL);
+
+        CR_XML_LOG (self->node);
+
+        return (char const *) self->node->name;
+}
+
+static char *
+get_attribute (CRNode const     *node,
+               char const       *name)
+{
+        CRXmlNode       *self = (CRXmlNode *) node;
+
+        g_return_val_if_fail (self, NULL);
+        g_return_val_if_fail (self->node, NULL);
+
+        return (char *) xmlGetProp (self->node, (xmlChar const *) name);
+}
+
+static guint
+get_children_count (CRNode const *node)
+{
+        CRXmlNode       *self = (CRXmlNode *) node;
+        xmlNode         *xnode;
+        guint            children_count;
+
+        g_return_val_if_fail (self, NULL);
+        g_return_val_if_fail (self->node, NULL);
+
+        children_count = 0;
+        for (xnode = self->node->children; xnode; xnode = xnode->next) {
+                if (xnode->type == XML_ELEMENT_NODE) {
+                        children_count++;
+                }
+        }
+
+        return children_count;
+}
+
+static guint
+get_index (CRNode const *node)
+{
+        CRXmlNode       *self = (CRXmlNode *) node;
+        xmlNode         *xnode;
+        guint            index;
+
+        g_return_val_if_fail (self, NULL);
+        g_return_val_if_fail (self->node, NULL);
+
+        index = 0;
+        for (xnode = self->node->parent->children; xnode; xnode = xnode->next) {
+                if (xnode == self->node) {
+                        break;
+                }
+                if (xnode->type == XML_ELEMENT_NODE) {
+                        index++;
+                }
+        }
+
+        return index;
+}
+
+static void
+release (CRNode *node)
+{
+        CRXmlNode       *self = (CRXmlNode *) node;
+
+        g_return_if_fail (self);
+
+        CR_XML_LOG (self->node);
+
+        g_free (self);
+}
+
+static CRNodeIface const *
+peek_node_iface (void)
+{
+        static CRNodeIface const _node_iface = {
+        	.get_parent_node        = get_parent_node,
+        	.get_first_child        = get_first_child,
+        	.get_next_sibling       = get_next_sibling,
+        	.get_previous_sibling   = get_previous_sibling,
+        	.get_node_name          = get_node_name,
+        	.get_attribute          = get_attribute,
+                .get_children_count     = get_children_count,
+                .get_index              = get_index,
+        	.release                = release
+        };
+
+        return &_node_iface;
+}
+
+enum CRStatus
+cr_xml_sel_eng_matches_node (CRSelEng       *a_this,
+                             CRSimpleSel    *a_sel,
+                             xmlNode        *a_node,
+                             gboolean       *a_result)
+{
+        CRXmlNode       *xnode;
+        enum CRStatus    ret;
+
+        g_return_val_if_fail (a_this && a_node
+                              && a_result, CR_BAD_PARAM_ERROR);
+
+        /* Look for an actual element if passed e.g. document. */
+        if (a_node->type != XML_ELEMENT_NODE) {
+                for (a_node = a_node->children; a_node; a_node = a_node->next) {
+                        if (a_node == XML_ELEMENT_NODE) {
+                                break;
+                        }
+                }
+        }
+        if (a_node == NULL) {
+                return CR_BAD_PARAM_ERROR;
+        }
+
+        xnode = (CRXmlNode *) cr_xml_node_new (a_node);
+        ret = cr_sel_eng_matches_node (a_this, a_sel, &xnode->base, a_result);
+        cr_xml_node_free (xnode);
+        return ret;
+}
+
+enum CRStatus
+cr_xml_sel_eng_get_matched_rulesets (CRSelEng          *a_this,
+                                     CRStyleSheet      *a_sheet,
+                                     xmlNode           *a_node,
+                                     CRStatement    ***a_rulesets,
+                                     gulong            *a_len)
+{
+        CRXmlNode       *xnode;
+        enum CRStatus    ret;
+
+        g_return_val_if_fail (a_this
+                              && a_sheet
+                              && a_node
+                              && a_rulesets && *a_rulesets == NULL
+                              && a_len, CR_BAD_PARAM_ERROR);
+
+        /* Look for an actual element if passed e.g. document. */
+        if (a_node->type != XML_ELEMENT_NODE) {
+                for (a_node = a_node->children; a_node; a_node = a_node->next) {
+                        if (a_node == XML_ELEMENT_NODE) {
+                                break;
+                        }
+                }
+        }
+        if (a_node == NULL) {
+                return CR_BAD_PARAM_ERROR;
+        }
+
+        xnode = (CRXmlNode *) cr_xml_node_new (a_node);
+        ret = cr_sel_eng_get_matched_rulesets (a_this, a_sheet, &xnode->base,
+                                               a_rulesets, a_len);
+        cr_xml_node_free (xnode);
+        return ret;
+}
+
+enum CRStatus
+cr_xml_sel_eng_get_matched_properties_from_cascade (CRSelEng         *a_this,
+                                                    CRCascade        *a_cascade,
+                                                    xmlNode          *a_node,
+                                                    CRPropList      **a_props)
+{
+        CRXmlNode       *xnode;
+        enum CRStatus    ret;
+
+        g_return_val_if_fail (a_this
+                              && a_cascade
+                              && a_node && a_props, CR_BAD_PARAM_ERROR);
+
+        /* Look for an actual element if passed e.g. document. */
+        if (a_node->type != XML_ELEMENT_NODE) {
+                for (a_node = a_node->children; a_node; a_node = a_node->next) {
+                        if (a_node == XML_ELEMENT_NODE) {
+                                break;
+                        }
+                }
+        }
+        if (a_node == NULL) {
+                return CR_BAD_PARAM_ERROR;
+        }
+
+        xnode = (CRXmlNode *) cr_xml_node_new (a_node);
+        ret = cr_sel_eng_get_matched_properties_from_cascade (a_this, a_cascade,
+                                                              &xnode->base,
+                                                              a_props);
+        cr_xml_node_free (xnode);
+        return ret;
+}
+
+enum CRStatus
+cr_xml_sel_eng_get_matched_style (CRSelEng     *a_this,
+                                  CRCascade    *a_cascade,
+                                  xmlNode      *a_node,
+                                  CRStyle      *a_parent_style,
+                                  CRStyle     **a_style,
+                                  gboolean      a_set_props_to_initial_values)
+{
+        CRXmlNode       *xnode;
+        enum CRStatus    ret;
+
+        g_return_val_if_fail (a_this && a_cascade
+                              && a_node && a_style, CR_BAD_PARAM_ERROR);
+
+        /* Look for an actual element if passed e.g. document. */
+        if (a_node->type != XML_ELEMENT_NODE) {
+                for (a_node = a_node->children; a_node; a_node = a_node->next) {
+                        if (a_node == XML_ELEMENT_NODE) {
+                                break;
+                        }
+                }
+        }
+        if (a_node == NULL) {
+                return CR_BAD_PARAM_ERROR;
+        }
+
+        xnode = (CRXmlNode *) cr_xml_node_new (a_node);
+        ret = cr_sel_eng_get_matched_style (a_this, a_cascade, &xnode->base,
+                                            a_parent_style, a_style,
+                                            a_set_props_to_initial_values);
+        cr_xml_node_free (xnode);
+        return ret;
+}
Index: src/cr-sel-eng.c
===================================================================
--- src/cr-sel-eng.c	(revision 326)
+++ src/cr-sel-eng.c	(working copy)
@@ -36,7 +36,7 @@
 #define PRIVATE(a_this) (a_this)->priv
 
 struct CRPseudoClassSelHandlerEntry {
-        guchar *name;
+        gchar *name;
         enum CRPseudoType type;
         CRPseudoClassSelectorHandler handler;
 };
@@ -57,17 +57,17 @@
 } ;
 
 static gboolean class_add_sel_matches_node (CRAdditionalSel * a_add_sel,
-                                            xmlNode * a_node);
+                                            CRNode const * a_node);
 
 static gboolean id_add_sel_matches_node (CRAdditionalSel * a_add_sel,
-                                         xmlNode * a_node);
+                                         CRNode const * a_node);
 
 static gboolean attr_add_sel_matches_node (CRAdditionalSel * a_add_sel,
-                                           xmlNode * a_node);
+                                           CRNode const * a_node);
 
 static enum CRStatus sel_matches_node_real (CRSelEng * a_this,
                                             CRSimpleSel * a_sel,
-                                            xmlNode * a_node,
+                                            CRNode const * a_node,
                                             gboolean * a_result,
                                             gboolean a_eval_sel_list_from_end,
                                             gboolean a_recurse);
@@ -75,7 +75,7 @@
 static enum CRStatus cr_sel_eng_get_matched_rulesets_real (CRSelEng * a_this,
                                                            CRStyleSheet *
                                                            a_stylesheet,
-                                                           xmlNode * a_node,
+                                                           CRNode const * a_node,
                                                            CRStatement **
                                                            a_rulesets,
                                                            gulong * a_len);
@@ -87,34 +87,27 @@
 static gboolean pseudo_class_add_sel_matches_node (CRSelEng * a_this,
                                                    CRAdditionalSel *
                                                    a_add_sel,
-                                                   xmlNode * a_node);
+                                                   CRNode const * a_node);
 
 static gboolean lang_pseudo_class_handler (CRSelEng * a_this,
                                            CRAdditionalSel * a_sel,
-                                           xmlNode * a_node);
+                                           CRNode const * a_node);
 
 static gboolean first_child_pseudo_class_handler (CRSelEng * a_this,
                                                   CRAdditionalSel * a_sel,
-                                                  xmlNode * a_node);
+                                                  CRNode const * a_node);
 
-static xmlNode *get_next_element_node (xmlNode * a_node);
-
-static xmlNode *get_next_child_element_node (xmlNode * a_node);
-
-static xmlNode *get_prev_element_node (xmlNode * a_node);
-
-static xmlNode *get_next_parent_element_node (xmlNode * a_node);
-
 /* Quick strcmp.  Test only for == 0 or != 0, not < 0 or > 0.  */
 #define strqcmp(str,lit,lit_len) \
   (strlen (str) != (lit_len) || memcmp (str, lit, lit_len))
 
 static gboolean
 lang_pseudo_class_handler (CRSelEng * a_this,
-                           CRAdditionalSel * a_sel, xmlNode * a_node)
+                           CRAdditionalSel * a_sel, CRNode const * a_node)
 {
-        xmlNode *node = a_node;
-        xmlChar *val = NULL;
+        CRNode const *node = a_node;
+        CRNode *child;
+        gchar *val = NULL;
         gboolean result = FALSE;
 
         g_return_val_if_fail (a_this && PRIVATE (a_this)
@@ -135,8 +128,11 @@
             || !a_sel->content.pseudo->extra->stryng
             || a_sel->content.pseudo->extra->stryng->len < 2)
                 return FALSE;
-        for (; node; node = get_next_parent_element_node (node)) {
-                val = xmlGetProp (node, "lang");
+
+        child = NULL;
+        for (; node; node = node->iface->get_parent_node (node)) {
+
+                val = node->iface->get_attribute (node, "lang");
                 if (val
                     && !strqcmp (val,
                                  a_sel->content.pseudo->extra->stryng->str,
@@ -144,19 +140,30 @@
                         result = TRUE;
                 }
                 if (val) {
-                        xmlFree (val);
+                        g_free (val);
                         val = NULL;
                 }
-        }
 
+                /* Taking care manually not to release a_node. */
+                if (child && child != a_node) {
+                        child->iface->release (child);
+                        child = NULL;
+                }
+                child = (CRNode *) node;
+        }
+        /* Taking care manually not to release a_node. */
+        if (child && child != a_node) {
+                child->iface->release (child);
+                child = NULL;
+        }
         return result;
 }
 
 static gboolean
 first_child_pseudo_class_handler (CRSelEng * a_this,
-                                  CRAdditionalSel * a_sel, xmlNode * a_node)
+                                  CRAdditionalSel * a_sel, CRNode const * a_node)
 {
-        xmlNode *node = NULL;
+        guint index;
 
         g_return_val_if_fail (a_this && PRIVATE (a_this)
                               && a_sel && a_sel->content.pseudo
@@ -171,18 +178,15 @@
                 cr_utils_trace_info ("This handler is for :first-child only");
                 return CR_BAD_PSEUDO_CLASS_SEL_HANDLER_ERROR;
         }
-        if (!a_node->parent)
-                return FALSE;
-        node = get_next_child_element_node (a_node->parent);
-        if (node == a_node)
-                return TRUE;
-        return FALSE;
+
+        index = a_node->iface->get_index (a_node);
+        return index == 0;
 }
 
 static gboolean
 pseudo_class_add_sel_matches_node (CRSelEng * a_this,
                                    CRAdditionalSel * a_add_sel,
-                                   xmlNode * a_node)
+                                   CRNode const * a_node)
 {
         enum CRStatus status = CR_OK;
         CRPseudoClassSelectorHandler handler = NULL;
@@ -211,10 +215,10 @@
  *the xml node given in argument, FALSE otherwise.
  */
 static gboolean
-class_add_sel_matches_node (CRAdditionalSel * a_add_sel, xmlNode * a_node)
+class_add_sel_matches_node (CRAdditionalSel * a_add_sel, CRNode const * a_node)
 {
         gboolean result = FALSE;
-        xmlChar *klass = NULL,
+        gchar *klass = NULL,
                 *cur = NULL;
 
         g_return_val_if_fail (a_add_sel
@@ -224,32 +228,30 @@
                               && a_add_sel->content.class_name->stryng->str
                               && a_node, FALSE);
 
-        if (xmlHasProp (a_node, "class")) {
-                klass = xmlGetProp (a_node, "class");
-                for (cur = klass; cur && *cur; cur++) {
-                        while (cur && *cur
-                               && cr_utils_is_white_space (*cur) 
-                               == TRUE)
-                                cur++;
+        klass = a_node->iface->get_attribute (a_node, "class");
+        for (cur = klass; cur && *cur; cur++) {
+                while (cur && *cur
+                        && cr_utils_is_white_space (*cur)
+                        == TRUE)
+                        cur++;
 
-                        if (!strncmp (cur, 
-                                      a_add_sel->content.class_name->stryng->str,
-                                      a_add_sel->content.class_name->stryng->len)) {
-                                cur += a_add_sel->content.class_name->stryng->len;
-                                if ((cur && !*cur)
-                                    || cr_utils_is_white_space (*cur) == TRUE)
-                                        result = TRUE;
-                        } else {  /* if it doesn't match,  */
-                                /*   then skip to next whitespace character to try again */
-                                while (cur && *cur && !(cr_utils_is_white_space(*cur) == TRUE)) 
-                                        cur++;
-                        }
-                        if (cur && !*cur)
-                                break ;
+                if (!strncmp (cur,
+                              a_add_sel->content.class_name->stryng->str,
+                              a_add_sel->content.class_name->stryng->len)) {
+                        cur += a_add_sel->content.class_name->stryng->len;
+                        if ((cur && !*cur)
+                            || cr_utils_is_white_space (*cur) == TRUE)
+                                result = TRUE;
+                } else {  /* if it doesn't match,  */
+                        /*   then skip to next whitespace character to try again */
+                        while (cur && *cur && !(cr_utils_is_white_space(*cur) == TRUE))
+                                cur++;
                 }
+                if (cur && !*cur)
+                        break ;
         }
         if (klass) {
-                xmlFree (klass);
+                g_free (klass);
                 klass = NULL;
         }
         return result;
@@ -263,10 +265,10 @@
  *@param a_node the xml node to consider.
  */
 static gboolean
-id_add_sel_matches_node (CRAdditionalSel * a_add_sel, xmlNode * a_node)
+id_add_sel_matches_node (CRAdditionalSel * a_add_sel, CRNode const * a_node)
 {
         gboolean result = FALSE;
-        xmlChar *id = NULL;
+        gchar *id = NULL;
 
         g_return_val_if_fail (a_add_sel
                               && a_add_sel->type == ID_ADD_SELECTOR
@@ -278,15 +280,11 @@
                               && a_add_sel->type == ID_ADD_SELECTOR
                               && a_node, FALSE);
 
-        if (xmlHasProp (a_node, "id")) {
-                id = xmlGetProp (a_node, "id");
-                if (!strqcmp (id, a_add_sel->content.id_name->stryng->str,
-                              a_add_sel->content.id_name->stryng->len)) {
-                        result = TRUE;
-                }
-        }
-        if (id) {
-                xmlFree (id);
+        id = a_node->iface->get_attribute (a_node, "id");
+        if (id && !strqcmp (id, a_add_sel->content.id_name->stryng->str,
+                        a_add_sel->content.id_name->stryng->len)) {
+                result = TRUE;
+                g_free (id);
                 id = NULL;
         }
         return result;
@@ -302,9 +300,10 @@
  *FALSE otherwise.
  */
 static gboolean
-attr_add_sel_matches_node (CRAdditionalSel * a_add_sel, xmlNode * a_node)
+attr_add_sel_matches_node (CRAdditionalSel * a_add_sel, CRNode const * a_node)
 {
         CRAttrSel *cur_sel = NULL;
+        gchar *value = NULL;
 
         g_return_val_if_fail (a_add_sel
                               && a_add_sel->type == ATTRIBUTE_ADD_SELECTOR
@@ -319,15 +318,18 @@
                             || !cur_sel->name->stryng->str)
                                 return FALSE;
 
-                        if (!xmlHasProp (a_node,
-                                         cur_sel->name->stryng->str))
+                        value = a_node->iface->get_attribute (a_node,
+                                         cur_sel->name->stryng->str);
+                        if (value) {
+                                g_free (value);
+                                value = NULL;
+                        } else {
                                 return FALSE;
+                        }
                         break;
 
                 case EQUALS:
                         {
-                                xmlChar *value = NULL;
-
                                 if (!cur_sel->name 
                                     || !cur_sel->name->stryng
                                     || !cur_sel->name->stryng->str
@@ -336,42 +338,32 @@
                                     || !cur_sel->value->stryng->str)
                                         return FALSE;
 
-                                if (!xmlHasProp 
-                                    (a_node, 
-                                     cur_sel->name->stryng->str))
-                                        return FALSE;
-
-                                value = xmlGetProp 
+                                value = a_node->iface->get_attribute
                                         (a_node,
                                          cur_sel->name->stryng->str);
-
-                                if (value
-                                    && strcmp 
-                                    (value, 
-                                     cur_sel->value->stryng->str)) {
-                                        xmlFree (value);
+                                if (value == NULL) {
                                         return FALSE;
+                                } else if (value
+                                           && strcmp (value,
+                                                      cur_sel->value->stryng->str)) {
+                                        g_free (value);
+                                        return FALSE;
                                 }
-                                xmlFree (value);
+                                g_free (value);
                         }
                         break;
 
                 case INCLUDES:
                         {
-                                xmlChar *value = NULL,
+                                gchar *value = NULL,
                                         *ptr1 = NULL,
                                         *ptr2 = NULL,
                                         *cur = NULL;
                                 gboolean found = FALSE;
 
-                                if (!xmlHasProp 
-                                    (a_node, 
-                                     cur_sel->name->stryng->str))
-                                        return FALSE;
-                                value = xmlGetProp 
+                                value = a_node->iface->get_attribute
                                         (a_node,
                                          cur_sel->name->stryng->str);
-
                                 if (!value)
                                         return FALSE;
 
@@ -412,29 +404,26 @@
                                 }
 
                                 if (found == FALSE) {
-                                        xmlFree (value);
+                                        g_free (value);
                                         return FALSE;
                                 }
-                                xmlFree (value);
+                                g_free (value);
                         }
                         break;
 
                 case DASHMATCH:
                         {
-                                xmlChar *value = NULL,
+                                gchar *value = NULL,
                                         *ptr1 = NULL,
                                         *ptr2 = NULL,
                                         *cur = NULL;
                                 gboolean found = FALSE;
 
-                                if (!xmlHasProp 
-                                    (a_node, 
-                                     cur_sel->name->stryng->str))
-                                        return FALSE;
-                                value = xmlGetProp 
+                                value = a_node->iface->get_attribute
                                         (a_node,
                                          cur_sel->name->stryng->str);
-
+                                if (!value)
+                                        return FALSE;
                                 /*
                                  *here, make sure value is an hyphen
                                  *separated list of "words", each of which
@@ -460,10 +449,10 @@
                                 }
 
                                 if (found == FALSE) {
-                                        xmlFree (value);
+                                        g_free (value);
                                         return FALSE;
                                 }
-                                xmlFree (value);
+                                g_free (value);
                         }
                         break;
                 default:
@@ -483,7 +472,7 @@
 static gboolean
 additional_selector_matches_node (CRSelEng * a_this,
                                   CRAdditionalSel * a_add_sel,
-                                  xmlNode * a_node)
+                                  CRNode const * a_node)
 {
         CRAdditionalSel *cur_add_sel = NULL, *tail = NULL ;
         gboolean evaluated = FALSE ;
@@ -546,63 +535,6 @@
         return FALSE ;
 }
 
-static xmlNode *
-get_next_element_node (xmlNode * a_node)
-{
-        xmlNode *cur_node = NULL;
-
-        g_return_val_if_fail (a_node, NULL);
-
-        cur_node = a_node->next;
-        while (cur_node && cur_node->type != XML_ELEMENT_NODE) {
-                cur_node = cur_node->next;
-        }
-        return cur_node;
-}
-
-static xmlNode *
-get_next_child_element_node (xmlNode * a_node)
-{
-        xmlNode *cur_node = NULL;
-
-        g_return_val_if_fail (a_node, NULL);
-
-        cur_node = a_node->children;
-        if (!cur_node)
-                return cur_node;
-        if (a_node->children->type == XML_ELEMENT_NODE)
-                return a_node->children;
-        return get_next_element_node (a_node->children);
-}
-
-static xmlNode *
-get_prev_element_node (xmlNode * a_node)
-{
-        xmlNode *cur_node = NULL;
-
-        g_return_val_if_fail (a_node, NULL);
-
-        cur_node = a_node->prev;
-        while (cur_node && cur_node->type != XML_ELEMENT_NODE) {
-                cur_node = cur_node->prev;
-        }
-        return cur_node;
-}
-
-static xmlNode *
-get_next_parent_element_node (xmlNode * a_node)
-{
-        xmlNode *cur_node = NULL;
-
-        g_return_val_if_fail (a_node, NULL);
-
-        cur_node = a_node->parent;
-        while (cur_node && cur_node->type != XML_ELEMENT_NODE) {
-                cur_node = cur_node->parent;
-        }
-        return cur_node;
-}
-
 /**
  *Evaluate a selector (a simple selectors list) and says
  *if it matches the xml node given in parameter.
@@ -623,12 +555,13 @@
  */
 static enum CRStatus
 sel_matches_node_real (CRSelEng * a_this, CRSimpleSel * a_sel,
-                       xmlNode * a_node, gboolean * a_result,
+                       CRNode const * a_node, gboolean * a_result,
                        gboolean a_eval_sel_list_from_end,
                        gboolean a_recurse)
 {
         CRSimpleSel *cur_sel = NULL;
-        xmlNode *cur_node = NULL;
+        CRNode *cur_node = NULL;
+        CRNode *prev_node = NULL;
 
         g_return_val_if_fail (a_this && PRIVATE (a_this)
                               && a_this && a_node
@@ -636,24 +569,23 @@
 
         *a_result = FALSE;
 
-        if (a_node->type != XML_ELEMENT_NODE)
-                return CR_OK;
-
         if (a_eval_sel_list_from_end == TRUE) {
                 /*go and get the last simple selector of the list */
                 for (cur_sel = a_sel;
-                     cur_sel && cur_sel->next; cur_sel = cur_sel->next) ;
+                     cur_sel && cur_sel->next;
+                     cur_sel = cur_sel->next) ;
         } else {
                 cur_sel = a_sel;
         }
 
-        for (cur_node = a_node; cur_sel; cur_sel = cur_sel->prev) {
+        /* We are taking care manually not to release cur_node == a_node. */
+        for (cur_node = (CRNode *) a_node; cur_sel; cur_sel = cur_sel->prev) {
                 if (((cur_sel->type_mask & TYPE_SELECTOR)
                      && (cur_sel->name 
                          && cur_sel->name->stryng
                          && cur_sel->name->stryng->str)
                      && (!strcmp (cur_sel->name->stryng->str,
-                                  cur_node->name)))
+                                  cur_node->iface->get_node_name (cur_node))))
                     || (cur_sel->type_mask & UNIVERSAL_SELECTOR)) {
                         /*
                          *this simple selector
@@ -663,7 +595,7 @@
                          *their xml node counterpart.
                          */
                         if (cur_sel->add_sel) {
-                                if (additional_selector_matches_node (a_this, cur_sel->add_sel, 
+                                if (additional_selector_matches_node (a_this, cur_sel->add_sel,
                                                                       cur_node) == TRUE) {
                                         goto walk_a_step_in_expr;
                                 } else {
@@ -709,7 +641,8 @@
 
                 case COMB_WS:  /*descendant selector */
                 {
-                        xmlNode *n = NULL;
+                        CRNode *n = NULL;
+                        CRNode *child;
                         enum CRStatus status = CR_OK;
                         gboolean matches = FALSE;
 
@@ -717,25 +650,52 @@
                          *walk the xml tree upward looking for a parent
                          *node that matches the preceding selector.
                          */
-                        for (n = cur_node->parent; n; n = n->parent) {
+                        child = NULL;
+                        for (n = cur_node->iface->get_parent_node (cur_node);
+                             n;
+                             n = n->iface->get_parent_node (n)) {
+
                                 status = sel_matches_node_real
                                         (a_this, cur_sel->prev,
                                          n, &matches, FALSE, TRUE);
 
-                                if (status != CR_OK)
+                                if (status != CR_OK) {
+                                        if (child) {
+                                                child->iface->release (child);
+                                                child = NULL;
+                                        }
                                         goto done;
+                                }
 
                                 if (matches == TRUE) {
-                                        cur_node = n ;
+                                        if (cur_node != a_node) {
+                                                cur_node->iface->release (cur_node);
+                                                cur_node = NULL;
+                                        }
+                                        cur_node = n;
                                         break;
                                 }
+
+                                if (child) {
+                                        child->iface->release (child);
+                                        child = NULL;
+                                }
+                                child = n;
                         }
+                        if (child) {
+                                child->iface->release (child);
+                                child = NULL;
+                        }
 
                         if (!n) {
                                 /*
                                  *didn't find any ancestor that matches
                                  *the previous simple selector.
                                  */
+                                if (cur_node != a_node) {
+                                        cur_node->iface->release (cur_node);
+                                        cur_node = NULL;
+                                }
                                 goto done;
                         }
                         /*
@@ -750,13 +710,23 @@
                 }
 
                 case COMB_PLUS:
-                        cur_node = get_prev_element_node (cur_node);
+                        prev_node = cur_node;
+                        cur_node = cur_node->iface->get_previous_sibling (cur_node);
+                        if (prev_node != a_node) {
+                                prev_node->iface->release (prev_node);
+                                prev_node = NULL;
+                        }
                         if (!cur_node)
                                 goto done;
                         break;
 
                 case COMB_GT:
-                        cur_node = get_next_parent_element_node (cur_node);
+                        prev_node = cur_node;
+                        cur_node = cur_node->iface->get_parent_node (cur_node);
+                        if (prev_node != a_node) {
+                                prev_node->iface->release (prev_node);
+                                prev_node = NULL;
+                        }
                         if (!cur_node)
                                 goto done;
                         break;
@@ -818,7 +788,7 @@
 static enum CRStatus
 cr_sel_eng_get_matched_rulesets_real (CRSelEng * a_this,
                                       CRStyleSheet * a_stylesheet,
-                                      xmlNode * a_node,
+                                      CRNode const * a_node,
                                       CRStatement ** a_rulesets,
                                       gulong * a_len)
 {
@@ -1137,11 +1107,11 @@
         }
         memset (PRIVATE (result), 0, sizeof (CRSelEngPriv));
         cr_sel_eng_register_pseudo_class_sel_handler
-                (result, (guchar *) "first-child",
+                (result, "first-child",
                  IDENT_PSEUDO, (CRPseudoClassSelectorHandler)
                  first_child_pseudo_class_handler);
         cr_sel_eng_register_pseudo_class_sel_handler
-                (result, (guchar *) "lang",
+                (result, "lang",
                  FUNCTION_PSEUDO, (CRPseudoClassSelectorHandler)
                  lang_pseudo_class_handler);
 
@@ -1162,7 +1132,7 @@
  */
 enum CRStatus
 cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng * a_this,
-                                              guchar * a_name,
+                                              gchar const * a_name,
                                               enum CRPseudoType a_type,
                                               CRPseudoClassSelectorHandler
                                               a_handler)
@@ -1264,7 +1234,7 @@
 
 enum CRStatus
 cr_sel_eng_get_pseudo_class_selector_handler (CRSelEng * a_this,
-                                              guchar * a_name,
+                                              gchar const * a_name,
                                               enum CRPseudoType a_type,
                                               CRPseudoClassSelectorHandler *
                                               a_handler)
@@ -1310,17 +1280,12 @@
  */
 enum CRStatus
 cr_sel_eng_matches_node (CRSelEng * a_this, CRSimpleSel * a_sel,
-                         xmlNode * a_node, gboolean * a_result)
+                         CRNode const * a_node, gboolean * a_result)
 {
         g_return_val_if_fail (a_this && PRIVATE (a_this)
                               && a_this && a_node
                               && a_result, CR_BAD_PARAM_ERROR);
 
-        if (a_node->type != XML_ELEMENT_NODE) {
-                *a_result = FALSE;
-                return CR_OK;
-        }
-
         return sel_matches_node_real (a_this, a_sel, 
                                       a_node, a_result, 
                                       TRUE, TRUE);
@@ -1347,7 +1312,7 @@
 enum CRStatus
 cr_sel_eng_get_matched_rulesets (CRSelEng * a_this,
                                  CRStyleSheet * a_sheet,
-                                 xmlNode * a_node,
+                                 CRNode const * a_node,
                                  CRStatement *** a_rulesets, gulong * a_len)
 {
         CRStatement **stmts_tab = NULL;
@@ -1413,7 +1378,7 @@
 enum CRStatus
 cr_sel_eng_get_matched_properties_from_cascade (CRSelEng * a_this,
                                                 CRCascade * a_cascade,
-                                                xmlNode * a_node,
+                                                CRNode const * a_node,
                                                 CRPropList ** a_props)
 {
         CRStatement **stmts_tab = NULL;
@@ -1514,7 +1479,7 @@
 enum CRStatus
 cr_sel_eng_get_matched_style (CRSelEng * a_this,
                               CRCascade * a_cascade,
-                              xmlNode * a_node,
+                              CRNode const * a_node,
                               CRStyle * a_parent_style, 
                               CRStyle ** a_style,
                               gboolean a_set_props_to_initial_values)
