diff --git a/mozilla/extensions/transformiix/source/xml/util/DOMHelper.cpp b/mozilla/extensions/transformiix/source/xml/util/DOMHelper.cpp
new file mode 100644
index 00000000000..5e00ce093a6
--- /dev/null
+++ b/mozilla/extensions/transformiix/source/xml/util/DOMHelper.cpp
@@ -0,0 +1,327 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is TransforMiiX XSLT processor.
+ *
+ * The Initial Developer of the Original Code is Keith Visco.
+ * Portions created by Keith Visco (C) 1999 Keith Visco.
+ * All Rights Reserved..
+ *
+ * Contributor(s):
+ * Keith Visco, kvisco@ziplink.net
+ * -- original author.
+ *
+ * $Id: DOMHelper.cpp,v 1.1 2000-02-22 11:12:57 kvisco%ziplink.net Exp $
+ */
+
+/**
+ * A class used to overcome DOM 1.0 deficiencies
+ * @author Keith Visco
+ * @version $Revision: 1.1 $ $Date: 2000-02-22 11:12:57 $
+**/
+
+#include "DOMHelper.h"
+
+
+/**
+ * Creates a new DOMHelper
+**/
+DOMHelper::DOMHelper() {};
+
+/**
+ * Delets this DOMHelper
+**/
+DOMHelper::~DOMHelper() {
+ ListIterator* iter = indexes.iterator();
+ while (iter->hasNext()) {
+ IndexState* idxState = (IndexState*)iter->next();
+ delete idxState;
+ }
+ delete iter;
+} //-- ~DOMHelper
+
+
+/**
+ * Returns the node which appears first in the document
+ * If this method is called with nodes from a different
+ * document, node1 will be returned.
+ * @return the node which appears first in document order
+**/
+Node* DOMHelper::appearsFirst(Node* node1, Node* node2) {
+
+ if (!node2) return node1;
+ if (!node1) return node2;
+
+ if (node1->getOwnerDocument() != node2->getOwnerDocument())
+ return node1;
+
+ OrderInfo* orderInfo1 = getDocumentOrder(node1);
+ OrderInfo* orderInfo2 = getDocumentOrder(node2);
+
+ int compare = orderInfo1->compareTo(orderInfo2);
+ if (compare > 0) return node2;
+ return node1;
+
+} //-- compareDocumentOrders
+
+/**
+ * Returns the parent of the given node. This method is available
+ * mainly to compensate for the fact that Attr nodes in DOM 1.0
+ * do not have parents. (Why??)
+ * @param node the Node to return the parent of
+**/
+Node* DOMHelper::getParentNode(Node* node) {
+
+ if (!node) return 0;
+ if (node->getNodeType() != Node::ATTRIBUTE_NODE)
+ return node->getParentNode();
+
+ Int32 key = (Int32)node;
+ MITREObjectWrapper* wrapper = 0;
+
+ wrapper = (MITREObjectWrapper*) parents.retrieve(key);
+ if (!wrapper) {
+ continueIndexing(node);
+ wrapper = (MITREObjectWrapper*) parents.retrieve(key);
+ }
+
+ if (wrapper) return (Node*)wrapper->object;
+ return 0;
+
+} //-- getParentNode
+
+
+//-------------------/
+//- Private Methods -/
+//-------------------/
+
+/**
+ * Adds the given child/parent mapping
+**/
+void DOMHelper::addParentReference(Node* child, Node* parent) {
+
+ Int32 key = (Int32)child;
+ MITREObjectWrapper* wrapper = (MITREObjectWrapper*) parents.retrieve(key);
+ if (!wrapper) {
+ wrapper = new MITREObjectWrapper();
+ parents.add(wrapper, key);
+ }
+ wrapper->object = parent;
+
+} //-- addParentReference
+
+/**
+ * Continues indexing until the given node has been indexed
+ * @param node the target Node
+**/
+void DOMHelper::continueIndexing(Node* node) {
+ if (!node) return;
+
+
+
+ MITREObjectWrapper* wrapper = 0;
+
+ //-- get indexing information
+ Document* doc = node->getOwnerDocument();
+ ListIterator* iter = indexes.iterator();
+ IndexState* idxState = 0;
+ while (iter->hasNext()) {
+ idxState = (IndexState*)iter->next();
+ if (idxState->document == doc) break;
+ idxState = 0;
+ }
+
+ if (!idxState) {
+ idxState = new IndexState();
+ indexes.add(idxState);
+ idxState->document = doc;
+ idxState->next = doc->getDocumentElement();
+ if (!idxState->next) idxState->done = MB_TRUE;
+ }
+
+ if (idxState->done) return;
+
+ MBool found = MB_FALSE;
+ MBool alreadyProcessed = MB_FALSE;
+
+ while (!found) {
+
+ if (!idxState->next) {
+ idxState->done = MB_TRUE;
+ break;
+ }
+
+ if (!alreadyProcessed) {
+ //-- index attributes
+ if (idxState->next->getNodeType() == Node::ELEMENT_NODE) {
+ Element* element = (Element*)idxState->next;
+ NamedNodeMap* atts = element->getAttributes();
+ if (atts) {
+ for (int i = 0; i < atts->getLength(); i++) {
+ Node* tmpNode = atts->item(i);
+ addParentReference(tmpNode, element);
+ if (node == tmpNode) found = MB_TRUE;
+ }
+ }
+ }
+ }
+
+ //-- set next node to check
+ if ((!alreadyProcessed) && (idxState->next->hasChildNodes())) {
+ Node* child = idxState->next->getFirstChild();
+ idxState->next = child;
+ }
+ else if (idxState->next->getNextSibling()) {
+ idxState->next = idxState->next->getNextSibling();
+ alreadyProcessed = MB_FALSE;
+ }
+ else {
+ idxState->next = getParentNode(idxState->next);
+ alreadyProcessed = MB_TRUE;
+ }
+ }
+
+} //-- continueIndexing
+
+
+/**
+ * Returns the child number of the given node. Numbering
+ * starts at 1 for all nodes except the Document node and
+ * attribute nodes which has child numbers of 0. The child
+ * number is calculated by counting the number of times
+ * Node#getPreviousSibling can be called.
+ * @param node a pointer to the node in which to return the
+ * child number of.
+ * @return the child number for the given node
+**/
+int DOMHelper::getChildNumber(Node* node) {
+
+ if (!node) return -1;
+
+ int c = 0;
+ Node* tmp = node;
+ switch (node->getNodeType()) {
+ case Node::DOCUMENT_NODE:
+ case Node::ATTRIBUTE_NODE:
+ break;
+ default:
+ while (tmp = tmp->getPreviousSibling()) ++c;
+ break;
+ }
+
+
+ return c;
+} //-- getChildNumber
+
+/**
+ * Returns the DocumentOrder for the given Node
+ * @param node a pointer to the Node in which to return the
+ * DocumentOrder of
+ * @return the DocumentOrder for the given Node
+**/
+OrderInfo* DOMHelper::getDocumentOrder(Node* node) {
+
+ if (!node) return 0;
+
+ Int32 key = (Int32)node;
+ OrderInfo* orderInfo = (OrderInfo*)orders.retrieve(key);
+
+ if (!orderInfo) {
+ if (node->getNodeType() == Node::DOCUMENT_NODE) {
+ orderInfo = new OrderInfo();
+ orderInfo->size = 1;
+ orderInfo->order = new int[1];
+ orderInfo->order[0] = 0;
+ }
+ else {
+ Node* parent = getParentNode(node);
+ OrderInfo* parentOrder = getDocumentOrder(parent);
+ orderInfo = new OrderInfo();
+
+ if (parentOrder) {
+ orderInfo->size = parentOrder->size+1;
+ orderInfo->order = new int[orderInfo->size];
+ int c = 0;
+ for ( ; c < parentOrder->size; c++)
+ orderInfo->order[c] = parentOrder->order[c];
+ orderInfo->order[c] = getChildNumber(node);
+ }
+ else {
+ orderInfo->size = 1;
+ orderInfo->order = new int[1];
+ orderInfo->order[0] = 0;
+ }
+ }
+ orders.add(orderInfo, key);
+ }
+
+ return orderInfo;
+
+} //-- getDocumentOrder
+
+//--------------------------------/
+//- implementation of IndexState -/
+//--------------------------------/
+
+/**
+ * Creates a new IndexState
+**/
+IndexState::IndexState() {
+ document = 0;
+ done = MB_FALSE;
+ next = 0;
+} //-- IndexState
+
+/**
+ * Deletes this IndexState
+**/
+IndexState::~IndexState() {};
+
+//-------------------------------/
+//- Implementation of OrderInfo -/
+//-------------------------------/
+
+/**
+ * Creates a new OrderInfo
+**/
+OrderInfo::OrderInfo() : MITREObject() {
+ order = 0;
+ size = 0;
+} //-- OrderInfo
+
+/**
+ * Deletes this OrderInfo
+**/
+OrderInfo::~OrderInfo() {
+ if (order) delete [] order;
+} //-- ~OrderInfo
+
+
+/**
+ * Compares this OrderInfo with the given OrderInfo
+ * @return -1 if this OrderInfo is less than the given OrderInfo;
+ * 0 if they are equal; 1 if this OrderInfo is greater.
+**/
+int OrderInfo::compareTo(OrderInfo* orderInfo) {
+
+ if (!orderInfo) return -1;
+
+ int c = 0;
+ while ( (c < size) && (c < orderInfo->size)) {
+ if (order[c] < orderInfo->order[c]) return -1;
+ else if (order[c] > orderInfo->order[c]) return 1;
+ ++c;
+ }
+ if (c < size) return 1;
+ else if (c < orderInfo->size) return -1;
+ return 0;
+
+} //-- compareTo
diff --git a/mozilla/extensions/transformiix/source/xml/util/DOMHelper.h b/mozilla/extensions/transformiix/source/xml/util/DOMHelper.h
new file mode 100644
index 00000000000..6985aec78e5
--- /dev/null
+++ b/mozilla/extensions/transformiix/source/xml/util/DOMHelper.h
@@ -0,0 +1,179 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is TransforMiiX XSLT processor.
+ *
+ * The Initial Developer of the Original Code is Keith Visco.
+ * Portions created by Keith Visco (C) 1999 Keith Visco.
+ * All Rights Reserved..
+ *
+ * Contributor(s):
+ * Keith Visco, kvisco@ziplink.net
+ * -- original author.
+ *
+ * $Id: DOMHelper.h,v 1.1 2000-02-22 11:12:57 kvisco%ziplink.net Exp $
+ */
+
+#ifndef TRANSFRMX_DOMHELPER_H
+#define TRANSFRMX_DOMHELPER_H
+
+#include "baseutils.h"
+#include "String.h"
+#include "List.h"
+#include "dom.h"
+#include "HashTable.h"
+#include "MITREObject.h"
+
+
+
+//----------------------/
+//- Class declarations -/
+//----------------------/
+
+/**
+ * A class used by DOMHelper to hold document order information
+ * for DOM Nodes
+**/
+class OrderInfo : public MITREObject {
+
+ public:
+
+ OrderInfo();
+ virtual ~OrderInfo();
+
+ int compareTo(OrderInfo* orderInfo);
+
+ int* order;
+ int size;
+
+}; //-- OrderInfo
+
+/**
+ * A class used to overcome DOM 1.0 deficiencies
+ * @author Keith Visco
+ * @version $Revision: 1.1 $ $Date: 2000-02-22 11:12:57 $
+**/
+class DOMHelper {
+
+public:
+
+ /**
+ * Creates a new DOMHelper
+ **/
+ DOMHelper();
+
+ /**
+ * Deletes this DOMHelper
+ **/
+ virtual ~DOMHelper();
+
+ /**
+ * Returns the node which appears first in the document
+ * (ie. has lower document order).
+ * If this method is called with nodes from a different
+ * document, node1 will be returned.
+ * @return the node which appears first in document order
+ **/
+ Node* appearsFirst(Node* node1, Node* node2);
+
+ /**
+ * Returns the child number of the given node. Numbering
+ * starts at 1 for all nodes except the Document node and
+ * attribute nodes which has child numbers of 0. The child
+ * number is calculated by counting the number of times
+ * Node#getPreviousSibling can be called.
+ * @param node a pointer to the node in which to return the
+ * child number of.
+ * @return the child number for the given node
+ **/
+ int getChildNumber(Node* node);
+
+ /**
+ * Returns the parent of the given node. This method is available
+ * mainly to compensate for the fact that Attr nodes in DOM 1.0
+ * do not have parents. (Why??)
+ * @param node the Node to return the parent of
+ **/
+ Node* getParentNode(Node* node);
+
+
+private:
+
+
+ /**
+ * Adds the given child/parent mapping to the list of parents
+ **/
+ void addParentReference(Node* child, Node* parent);
+
+ /**
+ * Indexes until the given node has been indexed
+ **/
+ void continueIndexing(Node* node);
+
+
+ /**
+ * Returns the DocumentOrder for the given Node
+ * @param node a pointer to the Node in which to return the
+ * DocumentOrder of
+ * @return the DocumentOrder for the given Node
+ **/
+ OrderInfo* getDocumentOrder(Node* node);
+
+
+ /**
+ * A Hashtable of attribute's parent nodes
+ **/
+ HashTable parents;
+
+ /**
+ * A Hashtable of Node/OrderInfo mappings
+ **/
+ HashTable orders;
+
+ /**
+ * A list of IndexState objects (one for each Document)
+ **/
+ List indexes;
+
+
+}; //-- DOMHelper
+
+/**
+ * A class which holds information about the current state of
+ * indexing
+**/
+class IndexState {
+
+ public:
+
+ IndexState();
+ ~IndexState();
+
+ /**
+ * The Document that this IndexState is for
+ **/
+ Document* document;
+
+ /**
+ * The next node to index
+ **/
+ Node* next;
+
+ /**
+ * A boolean indicating if the indexing has completed
+ **/
+ MBool done;
+
+}; //-- IndexState
+
+
+#endif
+
diff --git a/mozilla/extensions/transformiix/source/xml/util/Makefile b/mozilla/extensions/transformiix/source/xml/util/Makefile
new file mode 100644
index 00000000000..28f49c73267
--- /dev/null
+++ b/mozilla/extensions/transformiix/source/xml/util/Makefile
@@ -0,0 +1,11 @@
+
+INCLUDE_PATH = -I../../base -I../dom
+
+
+ALL_OBJS = DOMHelper.o
+
+
+target: $(ALL_OBJS)
+
+DOMHelper.o: DOMHelper.h DOMHelper.cpp
+ $(CC) $(INCLUDE_PATH) -c DOMHelper.cpp