/*
 * $Id: xbDOM2Core-impl.js,v 1.5 2003/09/14 21:22:26 bc Exp $
 *
 */

//  xbDOM 2.0 Core - A DOM Core API

/* ***** BEGIN LICENSE BLOCK *****
 * 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.
 * 
 * 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 Bob Clary code.
 *
 * The Initial Developer of the Original Code is
 * Bob Clary.
 * Portions created by the Initial Developer are Copyright (C) 2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <http://bclary.com/>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 * 
 ***** END LICENSE BLOCK ***** */

function xbDOM2GetDOMImplementation()
{
  return new xbDOM2_DOMImplementation();
}

// non xbDOM2_Node related classes
_classes.registerClass('xbDOM2_DOMImplementation');
_classes.registerClass('xbDOM2_NodeList', 'xbArray');
_classes.registerClass('xbDOM2_NamedNodeMap');

// xbDOM2_Node related classes
_classes.registerClass('xbDOM2_Node');
_classes.registerClass('xbDOM2_DocumentFragment',      'xbDOM2_Node');
_classes.registerClass('xbDOM2_Document',              'xbDOM2_Node');
_classes.registerClass('xbDOM2_CharacterData',         'xbDOM2_Node');
_classes.registerClass('xbDOM2_Attr',                  'xbDOM2_Node');
_classes.registerClass('xbDOM2_Element',               'xbDOM2_Node');
_classes.registerClass('xbDOM2_Text',                  'xbDOM2_CharacterData');
_classes.registerClass('xbDOM2_Comment',               'xbDOM2_CharacterData');
_classes.registerClass('xbDOM2_CDATASection',          'xbDOM2_Text');
_classes.registerClass('xbDOM2_DocumentType',          'xbDOM2_Node');
_classes.registerClass('xbDOM2_Notation',              'xbDOM2_Node');
_classes.registerClass('xbDOM2_Entity',                'xbDOM2_Node');
_classes.registerClass('xbDOM2_EntityReference',       'xbDOM2_Node');
_classes.registerClass('xbDOM2_ProcessingInstruction', 'xbDOM2_Node');

// xbDOM2_DOMImplementation

function xbDOM2_DOMImplementation()
{
  _classes.defineClass('xbDOM2_DOMImplementation', _prototype_func);
  
  this.init();

  function _prototype_func()
  {
    xbDOM2_DOMImplementation.prototype.hasFeature = hasFeature;
    function hasFeature(feature, version)
    {
      if (typeof(version) == 'undefined')
        version = '1.0';
        
      if (feature.match(/XML/i) && version.match(/(1.0|2.0)/))
        return true;
        
      return false;
    }
    
    xbDOM2_DOMImplementation.prototype.createDocument  = createDocument;
    function createDocument(namespaceURI, qName, doctype)
    {
      return new xbDOM2_Document(namespaceURI, qName, doctype, this);
    }
    
    xbDOM2_DOMImplementation.prototype.createDocumentType = createDocumentType;
    function createDocumentType(qname, publicId, systemId)
    {
      return new xbDOM2_DocumentType(qname, publicId, systemId, null);
    }
  }      
}
  
// xbDOM2_DocumentFragment

function xbDOM2_DocumentFragment(ownerDocument)
{
  _classes.defineClass('xbDOM2_DocumentFragment', _prototype_func);

  this.init(ownerDocument);

  function _prototype_func()
  {
    xbDOM2_DocumentFragment.prototype.init = init;
    function init(ownerDocument) 
    {
      this.parentMethod('init', '#document-fragment', null, DOCUMENT_FRAGMENT_NODE, ownerDocument)
      this.childNodes      =  new xbDOM2_NodeList();
    }
  }
}
  
// xbDOM2_Document

function xbDOM2_Document(namespaceURI, qName, doctype, implementation)
{
  _classes.defineClass('xbDOM2_Document', _prototype_func);
  
  this.init(namespaceURI, qName, doctype, implementation);

  function _prototype_func()
  {
    xbDOM2_Document.prototype.init = init;
    function init(namespaceURI, qName, doctype, implementation)
    {
      if (!namespaceURI) namespaceURI = null;
      if (!doctype) doctype = null;

      var namespaceData = xbDOM_ProcessNamespaceData(namespaceURI, qName);
            
      this.parentMethod('init', '#document', null, DOCUMENT_NODE, this);
      this.childNodes      =  new xbDOM2_NodeList();
      this.ownerDocument    = null;
      this.doctype      = doctype;
      this.implementation    = implementation;
      this.namespaceURI    = null;
      this.prefix        = null;
      this.localName      = null;
      
      if (namespaceURI)
        this.documentElement  = this.createElement(qName);
      else
        this.documentElement  = this.createElementNS(namespaceURI, qName);
      
      this.appendChild(this.documentElement);
    }
    
    xbDOM2_Document.prototype.destroy = destroy;
    function destroy()
    {
      this.implementation.destroy();
      if (this.doctype)
        this.doctype.destroy();
      
      this.ownerDocument    = null;
      //this.implementation    = null;
      //this.doctype      = null;
      //this.documentElement  = null;
      delete this.implementation;
      delete this.doctype;
      delete this.documentElement;

      this.parentMethod('destroy');
    }
    
    // DOM interface

    xbDOM2_Document.prototype.createAttribute = createAttribute;
    function createAttribute(name)
    {
      return new xbDOM2_Attr(name, null, this);
    }
    
    xbDOM2_Document.prototype.createAttributeNS = createAttributeNS;
    function createAttributeNS(namespaceURI, qualifiedName) 
    { 
      var namespaceData = xbDOM_ProcessNamespaceData(namespaceURI, qualifiedName);
      
      var attr = this.createAttribute(qualifiedName);
      
      attr.namespaceURI  = namespaceURI; 
      attr.prefix      = namespaceData.prefix;
      attr.localName    = namespaceData.localName;
      
      return attr;
    }
    
    xbDOM2_Document.prototype.createCDATASection = createCDATASection;
    function createCDATASection(data)
    {
      return new xbDOM2_CDATASection(data, this);
    }
    
    xbDOM2_Document.prototype.createComment = createComment;
    function createComment(data)
    {
      return new xbDOM2_Comment(data, this);
    }
    
    xbDOM2_Document.prototype.createDocumentFragment = createDocumentFragment;
    function createDocumentFragment()
    {
      return new xbDOM2_DocumentFragment(this);
    }
    
    xbDOM2_Document.prototype.createElement = createElement;
    function createElement(tagName)
    {
      return new xbDOM2_Element(tagName, this);
    }
    
    xbDOM2_Document.prototype.createElementNS = createElementNS;
    function createElementNS(namespaceURI, qualifiedName) 
    { 
      var namespaceData = xbDOM_ProcessNamespaceData(namespaceURI, qualifiedName);
      
      var elm = this.createElement(qualifiedName);
      
      elm.namespaceURI  = namespaceURI; 
      elm.prefix      = namespaceData.prefix;
      elm.localName    = namespaceData.localName;
      
      return elm;
    }
    
    xbDOM2_Document.prototype.createEntityReference = createEntityReference;
    function createEntityReference(name)
    {
      return new xbDOM2_EntityReference(name, this);
    }
    
    xbDOM2_Document.prototype.createProcessingInstruction  = createProcessingInstruction;
    function createProcessingInstruction(target, data)
    {
      return new xbDOM2_ProcessingInstruction(target, data, this);
    }
    
    xbDOM2_Document.prototype.createTextNode = createTextNode;
    function createTextNode(data)
    {
      return new xbDOM2_Text(data, this);
    }
    
    xbDOM2_Document.prototype.getElementsByTagName = getElementsByTagName;
    function getElementsByTagName(tagname) 
    {
      return this.documentElement.getElementsByTagName(tagname);
    }

    xbDOM2_Document.prototype.getElementsByTagNameNS = 
    function getElementsByTagNameNS(namespaceURI, localName) 
    { 
      return this.documentElement.getElementsByTagNameNS(namespaceURI, localName); 
    }
    
    xbDOM2_Document.prototype.importNode = 
    function importNode(importedNode, deep) 
    {
      var i;
      var newNode = this._createNode(importedNode.nodeName, importedNode.nodeValue, importedNode.nodeType);
      newNode._setUserData(importedNode._getUserData());
      
      if (importedNode.nodeType == ELEMENT_NODE)
      {
        var attr;
        for (i = 0; i < importedNode.attributes.length; i++)
        {
          attr = importedNode.attributes.item(i).importNode(deep);
          importedNode.attributes.setNamedItem(attr);
        }
      }
      
      if (deep)
      {
        var tmpChild = importedNode.firstChild;
        var childNode;
        
        while (tmpChild)
        {
          childNode = tmpChild.cloneNode(deep);
          newNode.appendChild(childNode);
          tmpChild = tmpChild.nextSibling;
        }  
      }
      return newNode;
    }

    // getter/setter methods
    
    xbDOM2_Document.prototype.getDocType = getDocType;
    function getDocType() 
    {
      return this.doctype;
    }
    
    xbDOM2_Document.prototype._setDocType = _setDocType;
    function _setDocType(doctype) 
    {
      this.doctype = doctype;
    }
    
    xbDOM2_Document.prototype.getImplementation = getImplementation;
    function getImplementation() 
    {
      return this.implementation;
    }
    
    xbDOM2_Document.prototype._setImplementation = _setImplementation;
    function _setImplementation(implementation) 
    {
      this.implementation = implementation;
    }
    
    xbDOM2_Document.prototype.getDocumentElement = getDocumentElement;
    function getDocumentElement() 
    {
      return this.documentElement;
    }
    
    xbDOM2_Document.prototype._setDocumentElement = _setDocumentElement;
    function _setDocumentElement(element) 
    {
      this.documentElement = element;
    }

    // non standard 
    xbDOM2_Document.prototype.toXML = toXML;
    function toXML()
    {
      var i;
      var childNodes = this.getChildNodes();
      var length     = childNodes.getLength()
      var child;
      var s          = '';
      
      for (i = 0; i < length; i++)
      {
        child = childNodes.item(i);
        if (child.toXML)
          s += child.toXML();
      }
      return s;
    }

    // Factory methods
    xbDOM2_Document.prototype._createNode      = _createNode;
    function _createNode(nodeName, nodeValue, nodeType)
    { 
      return new xbDOM2_Node(nodeName, nodeValue, nodeType, this);
    }

    xbDOM2_Document.prototype._createNodeList = _createNodeList;
    function _createNodeList() 
    { return new xbDOM2_NodeList(); }

    xbDOM2_Document.prototype._createNamedNodeMap  = _createNamedNodeMap;
    function _createNamedNodeMap() 
    { return new xbDOM2_NamedNodeMap(); }
  }
}

// xbDOM2_Node

function xbDOM2_Node(nodeName, nodeValue, nodeType, ownerDocument)
{
  _classes.defineClass('xbDOM2_Node', _prototype_func);
    
  this.init(nodeName, nodeValue, nodeType, ownerDocument);

  function _prototype_func()
  {
    xbDOM2_Node.prototype.nodeName        = null;
    xbDOM2_Node.prototype.nodeValue       = null;
    xbDOM2_Node.prototype.nodeType        = 0;
    xbDOM2_Node.prototype.childNodes      = new xbDOM2_NodeList();
    xbDOM2_Node.prototype.parentNode      = null;
    xbDOM2_Node.prototype.firstChild      = null;
    xbDOM2_Node.prototype.lastChild       = null;
    xbDOM2_Node.prototype.previousSibling = null;
    xbDOM2_Node.prototype.nextSibling     = null;
    xbDOM2_Node.prototype.attributes      = null;
    xbDOM2_Node.prototype.ownerDocument   = null;
    xbDOM2_Node.prototype.namespaceURI    = null;
    xbDOM2_Node.prototype.prefix          = null;
    xbDOM2_Node.prototype.localName       = null;
    xbDOM2_Node.prototype._userdata       = null;

    xbDOM2_Node.prototype.init = init;
    function init(nodeName, nodeValue, nodeType, ownerDocument)
    {
      this.parentMethod('init');
      
      if (!nodeName)      nodeName      = null;
      if (!nodeValue)     nodeValue     = null;
      if (!nodeType)      nodeType      = 0;
      if (!ownerDocument) ownerDocument = null;
      
      if (typeof(nodeName) == 'string')
      {
        if (!nodeName.match(/^[a-zA-Z_#][\w\-\.\:]*$/))
          throw (new xbDOM_DOMException(INVALID_CHARACTER_ERR));
      }
          
      if (nodeName)
        this.nodeName      = nodeName;
      if (nodeValue)
        this.nodeValue     = nodeValue;
      if (nodeType)
        this.nodeType      = nodeType;
      if (ownerDocument)
        this.ownerDocument = ownerDocument;

      // use the direct class instead of the factory method
      // since Document may or may not be constructed yet.      
      // use the prototype object unless node can have children
      //this.childNodes      =  new xbDOM2_NodeList();

      /*
      this.parentNode      = null;
      this.firstChild      = null;
      this.lastChild       = null;
      this.previousSibling = null;
      this.nextSibling     = null;
      this.attributes      = null;
      this.namespaceURI    = null;
      this.prefix          = null;
      this.localName       = null;
      this._userdata       = null;
      */
    }
    
    xbDOM2_Node.prototype.destroy = destroy; 
    function destroy()
    {
      this.childNodes.destroy();
        
      if (this.attributes)
        this.attributes.destroy();
        
      /*
      this.nodeName      = null;
      this.nodeValue      = null;
      this.nodeType      = null;      
      this.childNodes      = null;
      this.parentNode      = null;
      this.firstChild      = null;
      this.lastChild      = null;
      this.previousSibling  = null;
      this.nextSibling    = null;
      this.attributes      = null;
      this.ownerDocument    = null;
      this.namespaceURI    = null;
      this.prefix        = null;
      this.localName      = null;
      this._userdata      = null;
      */
      delete this.nodeName;
      delete this.nodeValue;
      delete this.nodeType;
      delete this.childNodes;
      delete this.parentNode;
      delete this.firstChild;
      delete this.lastChild;
      delete this.previousSibling;
      delete this.nextSibling;
      delete this.attributes;
      delete this.ownerDocument;
      delete this.namespaceURI;
      delete this.prefix;
      delete this.localName;
      delete this._userdata;
            
      this.parentMethod('destroy');
    }

    xbDOM2_Node.prototype.insertBefore = insertBefore;
    function insertBefore(newChild, refChild)
    {
      if (newChild.nodeType != DOCUMENT_FRAGMENT_NODE)
        this.__checkHierarchy(newChild);
      
      if (this.getOwnerDocument() != newChild.getOwnerDocument())
        throw(new xbDOM_DOMException(WRONG_DOCUMENT_ERR));

      if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE)
      {
        var currChild = newChild.lastChild;
        var prevChild;
        
        while (currChild)
        {
          prevChild = currChild.previousSibling;
          this.insertBefore(currChild, refChild);
          refChild = currChild;
          currChild = prevChild;
        }
          
        return newChild;
      }

      if (!refChild)
      {
        this.appendChild(newChild);
        return newChild;
      }

      var parentNode = newChild.parentNode;
      if (parentNode)
      {
        parentNode.removeChild(newChild);
      }
        
      var ok            = false;
      var tmpChildNodes = this.getOwnerDocument()._createNodeList();
      var tmpChild    = this.firstChild;
    
      while (tmpChild)
      {
        if (tmpChild == refChild)
        {
          newChild.nextSibling = refChild;
          newChild.previousSibling = refChild.previousSibling;

          if (newChild.previousSibling)
            newChild.previousSibling.nextSibling = newChild;

          refChild.previousSibling = newChild;
          newChild.parentNode = this;
          ok = true;
          tmpChildNodes.push(newChild);
        }
        tmpChildNodes.push(tmpChild);
        tmpChild = tmpChild.nextSibling;
      }

      if (!ok)
        throw(new xbDOM_DOMException(NOT_FOUND_ERR));
        
      this.childNodes = tmpChildNodes;
      this.firstChild = this.childNodes.item(0);
      this.lastChild = this.childNodes.item(this.childNodes.length-1);
    
      return newChild;
    }
    
    xbDOM2_Node.prototype.replaceChild = replaceChild;
    function replaceChild(newChild, oldChild)
    {
      this.__checkHierarchy(newChild);
      
      if (this.getOwnerDocument() != newChild.getOwnerDocument())
        throw(new xbDOM_DOMException(WRONG_DOCUMENT_ERR));
        
      var tmpChildNodes = this.getOwnerDocument()._createNodeList();
    
      if (!newChild)
      {
        this.removeChild(oldChild);
        return oldChild;
      }
      
      var parentNode = newChild.parentNode;
      if (parentNode)
      {
        parentNode.removeChild(newChild);
      }
        
      var ok = false;
      var tmpChild = this.firstChild;
      
      while (tmpChild)
      {
        if (tmpChild == oldChild)
        {
          newChild.nextSibling = oldChild.nextSibling;
          newChild.previousSibling = oldChild.previousSibling;

          if (newChild.nextSibling)
            newChild.nextSibling.previousSibling = newChild;

          if (newChild.previousSibling)
            newChild.previousSibling.nextSibling = newChild;

          tmpChildNodes.push(newChild);
          ok = true;
        }
        else
          tmpChildNodes.push(tmpChild);
          
        tmpChild = tmpChild.nextSibling;
      }
      
      if (!ok)
        throw(new xbDOM_DOMException(NOT_FOUND_ERR))
        
      this.childNodes = tmpChildNodes;
      this.firstChild = this.childNodes.item(0);
      this.lastChild  = this.childNodes.item(this.childNodes.length-1);
      
      newChild.parentNode = this;

      oldChild.parentNode = null;
    
      return oldChild;
    }

    xbDOM2_Node.prototype.removeChild = removeChild;
    function removeChild(oldChild)
    {
      var ok = false;
      var tmpChildNodes = this.getOwnerDocument()._createNodeList();
      var tmpChild = this.firstChild;
    
      while (tmpChild)
      {
        if (tmpChild == oldChild)
        {
          if (oldChild.nextSibling)
            oldChild.nextSibling.previousSibling = oldChild.previousSibling;
            
          if (oldChild.previousSibling)
            oldChild.previousSibling.nextSibling = oldChild.nextSibling;
        
          ok = true;
        }
        else
          tmpChildNodes.push(tmpChild);
          
        tmpChild = tmpChild.nextSibling;
      }
      
      if (!ok)
        throw (new xbDOM_DOMException(NOT_FOUND_ERR));
        
      this.childNodes     = tmpChildNodes;

      if (this.childNodes.length == 0)
      {
        this.firstChild = null;
        this.lastChild  = null;
      }
      else
      {
        this.firstChild = this.childNodes.item(0);
        this.lastChild = this.childNodes.item(this.childNodes.length-1);
      }
      
      oldChild.parentNode = null;
      oldChild.previousSibling = null;
      oldChild.nextSibling = null;
    
      return oldChild;
    }
    
    xbDOM2_Node.prototype.appendChild = appendChild;
    function appendChild(newChild)
    {
      if (newChild.nodeType != DOCUMENT_FRAGMENT_NODE)
        this.__checkHierarchy(newChild);
      
      if (this.getOwnerDocument() != newChild.getOwnerDocument())
        throw(new xbDOM_DOMException(WRONG_DOCUMENT_ERR));
        
      if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE)
      {
        // since appendChild modifies the nextSibling reference
        // we must save the next node before calling appendChild...
        var tmpChild = newChild.firstChild;
        var nextChild;
        
        while (tmpChild)
        {
          nextChild = tmpChild.nextSibling;
          this.appendChild(tmpChild);
          tmpChild = nextChild;
        }
      }
      else
      {
        var oldLastChild = this.lastChild;
      
        this.childNodes.push(newChild);

        if (!this.firstChild)
          this.firstChild = newChild;
          
        if (this.lastChild)
          this.lastChild.nextSibling = newChild;
          
        this.lastChild = newChild;
          
        newChild.parentNode = this;
        newChild.previousSibling = oldLastChild;
        newChild.nextSibling     = null;
      }
      
      return newChild;
    }
    
    xbDOM2_Node.prototype.hasChildNodes  = hasChildNodes;
    function hasChildNodes() {return this.firstChild != null;}

    xbDOM2_Node.prototype.cloneNode    = cloneNode;
    function cloneNode(deep)
    {
      var i;
      var newNode = this.getOwnerDocument()._createNode(this.nodeName, this.nodeValue, this.nodeType);
      newNode._setUserData(this._getUserData());
      
      if (this.nodeType == ELEMENT_NODE)
      {
        var attr;
        for (i = 0; i < this.attributes.length; i++)
        {
          attr = this.attributes.item(i).cloneNode(deep);
          this.attributes.setNamedItem(attr);
        }
      }
      
      if (deep)
      {
        var tmpChild = this.firstChild;
        var childNode;
        
        while (tmpChild)
        {
          childNode = tmpChild.cloneNode(deep);
          newNode.appendChild(childNode);
          tmpChild = tmpChild.nextSibling;
        }  
      }
      return newNode;
    }

    xbDOM2_Node.prototype.supports = supports;
    function supports(sFeature, sVersion) 
    { 
      return this.getOwnerDocument().implementation.hasFeature(sFeature, sVersion); 
    }

    // getter/setter methods
    
    xbDOM2_Node.prototype.getNodeName = getNodeName;
    function getNodeName() 
    {
      return this.nodeName;
    }
    
    xbDOM2_Node.prototype._setNodeName = _setNodeName;
    function _setNodeName(nodeName) 
    {
      this.nodeName = nodeName;
    }
    
    xbDOM2_Node.prototype.getNodeValue = getNodeValue;
    function getNodeValue() 
    {
      return this.nodeValue;  
    }
    
    xbDOM2_Node.prototype.setNodeValue = setNodeValue;
    function setNodeValue(nodeValue) 
    {
      this.nodeValue = nodeValue;
    }
    
    xbDOM2_Node.prototype.getNodeType = getNodeType;
    function getNodeType() 
    {
      return this.nodeType;
    }
    
    xbDOM2_Node.prototype._setNodeType = _setNodeType;
    function _setNodeType(nodeType) 
    {
      this.nodeType = nodeType;
    }
    
    xbDOM2_Node.prototype.getParentNode = getParentNode;
    function getParentNode() 
    {
      return this.parentNode;
    }
    
    xbDOM2_Node.prototype._setParentNode = _setParentNode;
    function _setParentNode(node) 
    {
      this.parentNode = node;
    }
    
    xbDOM2_Node.prototype.getChildNodes = getChildNodes;
    function getChildNodes() 
    {
      return this.childNodes;
    }
    
    xbDOM2_Node.prototype._setChildNodes = _setChildNodes;
    function _setChildNodes(childNodes) 
    {
      this.childNodes = childNodes;
    }
    
    xbDOM2_Node.prototype.getFirstChild = getFirstChild;
    function getFirstChild() 
    {
      return this.firstChild;
    }
    
    xbDOM2_Node.prototype._setFirstChild = _setFirstChild;
    function _setFirstChild(node) 
    {
      this.firstChild = node;  
    }
    
    xbDOM2_Node.prototype.getLastChild = getLastChild;
    function getLastChild() 
    {
      return this.lastChild;
    }
    
    xbDOM2_Node.prototype._setLastChild = _setLastChild;
    function _setLastChild(node) 
    {
      this.lastChild = node;
    }
    
    xbDOM2_Node.prototype.getPreviousSibling = getPreviousSibling;
    function getPreviousSibling() 
    {
      return this.previousSibling;
    }
    
    xbDOM2_Node.prototype._setPreviousSibling = _setPreviousSibling;
    function _setPreviousSibling(node) 
    {
      this.previousSibling = node;
    }
    
    xbDOM2_Node.prototype.getNextSibling = getNextSibling;
    function getNextSibling() 
    {
      return this.nextSibling;
    }
    
    xbDOM2_Node.prototype._setNextSibling = _setNextSibling;
    function _setNextSibling(node) 
    {
      this.nextSibling = node;
    }
    
    xbDOM2_Node.prototype.getAttributes = getAttributes;
    function getAttributes() 
    {
      return this.attributes;
    }
    
    xbDOM2_Node.prototype._setAttributes = _setAttributes;
    function _setAttributes(attributes) 
    {
      this.attributes = attributes;
    }
    
    xbDOM2_Node.prototype.getOwnerDocument = getOwnerDocument;
    function getOwnerDocument() 
    {
      if (this.ownerDocument == null)
        return this;
      else
        return this.ownerDocument;
    }
    
    xbDOM2_Node.prototype._setOwnerDocument  = _setOwnerDocument;
    function _setOwnerDocument(ownerDocument) 
    {
      this.ownerDocument = ownerDocument;
    }
    
    xbDOM2_Node.prototype.getNamespaceURI = getNamespaceURI; 
    function getNamespaceURI() 
    {
      return this.namespaceURI; 
    }
    
    xbDOM2_Node.prototype._setNamespaceURI = _setNamespaceURI;
    function _setNamespaceURI(namespaceURI) 
    { 
      this.namespaceURI = namespaceURI; 
    }

    xbDOM2_Node.prototype.getPrefix = getPrefix;
    function getPrefix() 
    {
      return this.prefix; 
    }

    xbDOM2_Node.prototype._setPrefix = _setPrefix;
    function _setPrefix(prefix) 
    {
      this.prefix = prefix; 
    }

    xbDOM2_Node.prototype.getLocalName = getLocalName;
    function getLocalName() 
    {
      return this.localName; 
    }

    xbDOM2_Node.prototype._setLocalName = 
    function _setLocalName(localName) 
    {
      this.localName = localName; 
    }

    xbDOM2_Node.prototype._getUserData = _getUserData;
    function _getUserData() 
    {
      return this._userdata;
    }
    
    xbDOM2_Node.prototype._setUserData = _setUserData;
    function _setUserData(userdata) 
    {
      this._userdata = userdata; 
    }
    
    xbDOM2_Node.prototype.isEqualTo = isEqualTo;
    function isEqualTo(node)
    {
      if (this == node)
        return true;
      return false;
    }

    xbDOM2_Node.prototype.__checkHierarchy  = __checkHierarchy;
  }
}

// xbDOM2_NodeList 

function xbDOM2_NodeList()
{
  _classes.defineClass('xbDOM2_NodeList', _prototype_func);
  
  this.init();

  function _prototype_func() 
  {
  }
}


// xbDOM2_NamedNodeMap

function xbDOM2_NamedNodeMap()
{
  _classes.defineClass('xbDOM2_NamedNodeMap', _prototype_func);

  this.init();    

  function _prototype_func()
  {
    xbDOM2_NamedNodeMap.prototype.init = init;
    function init()
    {
      this.parentMethod('init');
      this.map = new Object();  
      this.length = 0;
    }
    
    xbDOM2_NamedNodeMap.prototype.destroy = destroy;
    function destroy()
    {
      var p;
      
      for (p in this.map)
      {
        this.map[p].destroy();
        this.map[p] = null;
      }
        
      //this.map = null;
      delete this.map;
      delete this.length;
      this.parentMethod('destroy');
    }
        
    xbDOM2_NamedNodeMap.prototype.getNamedItem = getNamedItem; 
    function getNamedItem(name) 
    {
      var node = this.map[name];
      
      if (typeof(node) == 'undefined')
        return null;

      return node;
    }
    
    xbDOM2_NamedNodeMap.prototype.getNamedItemNS = getNamedItemNS;
    function getNamedItemNS(namespaceURI, name)
    {
      return this.getNamedItem( (namespaceURI == null ? '' : namespaceURI) + name );
    }
    
    xbDOM2_NamedNodeMap.prototype.item = item;
    function item(index)
    {
      var i = 0;
      var name;
      
      for (name in this.map)
      {
        if (i == index)
          return this.map[name];
        else
          ++i;
      }
      return null;
    }
    
    xbDOM2_NamedNodeMap.prototype.removeNamedItem = removeNamedItem;
    function removeNamedItem(name)
    {
      var node = this.map[name];
      if (!node)
        throw( new xbDOM_DOMException(NOT_FOUND_ERR) );
        
      this.length--;
      delete this.map[name];

      return node;
    }

    xbDOM2_NamedNodeMap.prototype.removeNamedItemNS = removeNamedItemNS;
    function removeNamedItemNS(namespaceURI, name)
    {
      return this.removeNamedItem( (namespaceURI == null ? '' : namespaceURI) + name );
    }
    
    xbDOM2_NamedNodeMap.prototype.setNamedItem = setNamedItem;
    function setNamedItem(node)
    {
      if (!this.map[node.nodeName])
        this.length += 1;
        
      this.map[node.nodeName] = node;
      return node;
    }

    xbDOM2_NamedNodeMap.prototype.setNamedItemNS = setNamedItemNS;
    function setNamedItemNS(node)
    {
      return this.setNamedItem( (namespaceURI == null ? '' : namespaceURI) + name );
    }

    // getter/setter methods
    xbDOM2_NamedNodeMap.prototype.getLength  = getLength;
    function getLength() 
    {
      return this.length;
    }
    
    xbDOM2_NamedNodeMap.prototype._setLength = _setLength;
    function _setLength(length) 
    {
      this.length = length;
    }
  }
}

// xbDOM2_CharacterData

function xbDOM2_CharacterData(data, ownerDocument)
{
  _classes.defineClass('xbDOM2_CharacterData', _prototype_func);
    
  this.init(data, ownerDocument);

  function _prototype_func()
  {
    xbDOM2_CharacterData.prototype.init = init;
    function init(data, ownerDocument) 
    {
      this.parentMethod('init', null, null, 0, ownerDocument);  
      
      if (!data) data = null;
      
      this.data       = data;
      this.nodeValue  = data;
      this.length     = 0;
      
      if (data)
        this.length = data.length;
    }
        
    xbDOM2_CharacterData.prototype.destroy = destroy;
    function destroy()
    {
      //this.data   = null;
      //this.length = null;
      delete this.data;
      delete this.length;
      this.parentMethod('destroy');
    }

    // DOM  interface
    
    xbDOM2_CharacterData.prototype.appendData = appendData;
    function appendData(arg)
    {
      this.setData(this.getData() + arg);
    }
    
    xbDOM2_CharacterData.prototype.insertData = insertData;
    function insertData(offset, arg)
    {
      if (offset >= this.length || offset < 0)
        throw(new xbDOM_DOMException(INDEX_SIZE_ERR));
        
      var data = this.getData();
      
      if (offset == 0)
        data = arg + data;
      else
        data = data.substr(0, offset - 1) + arg + data.substr(offset);
        
      this.setData(data);
    }
    
    xbDOM2_CharacterData.prototype.deleteData = deleteData;
    function deleteData(offset, count)
    {
      if (offset >= this.length || offset < 0 || count < 0)
        throw(new xbDOM_DOMException(INDEX_SIZE_ERR));
        
      var data = this.getData();
      
      if (offset == 0)
        data = data.substr(count);
      else
        data = data.substr(0, offset - 1) + data.substr(offset + count)
        
      this.setData(data);
    }
    
    xbDOM2_CharacterData.prototype.replaceData = replaceData;
    function replaceData(offset, count, arg)
    {
      if (offset >= this.length || offset < 0 || count < 0)
        throw(new xbDOM_DOMException(INDEX_SIZE_ERR));

      var data = this.getData();
      var length = this.getLength();        
      var i = 0;
      
      while ( i < count & offset + i < length)
      {
        data[offset + i] = arg[i];
        ++i;
      }
      this.setData(data);      
    }

    xbDOM2_CharacterData.prototype.substringData = substringData;
    function substringData(offset, count) 
    {
      if (offset >= this.length || offset < 0 || count < 0)
        throw(new xbDOM_DOMException(INDEX_SIZE_ERR));
        
      return this.data.substr(offset, count);
    }

    // getter/setter methods
    
    xbDOM2_CharacterData.prototype.getData = getData;
    function getData() 
    {
      if (this.data != this.nodeValue)
        throw( new xbException('data/nodeValue out of sync', 'xbDOM2_core.js', 'xbDOM2_CharacterData::getData'));
        
      return this.data;
    }
    
    xbDOM2_CharacterData.prototype.setData = setData;
    function setData(data) 
    {
      if (this.data != this.nodeValue)
        throw( new xbException('data/nodeValue out of sync', 'xbDOM2_core.js', 'xbDOM2_CharacterData::getData'));
        
      this.nodeValue = this.data = data; 
      this.length = data.length;
    }
    
    xbDOM2_CharacterData.prototype.getLength = getLength;
    function getLength() 
    {
      return this.length;
    }
    
    xbDOM2_CharacterData.prototype._setLength = _setLength;
    function _setLength(length)  
    {
      this.length = length;
    }

  }
}

// xbDOM2_Attr

function xbDOM2_Attr(name, value, ownerDocument)
{
  _classes.defineClass('xbDOM2_Attr', _prototype_func);
  
  this.init(name, value, ownerDocument);

  function _prototype_func()
  {
    xbDOM2_Attr.prototype.init = init;
    function init(name, value, ownerDocument)
    {
      if (!name) name = null;
      if (!value) value = null;
      
      this.parentMethod('init', name, value, ATTRIBUTE_NODE, ownerDocument);

      this.name      = name;
      this.value      = value;
      this.specified    = false;
      this.ownerElement  = null;
    }
    
    xbDOM2_Attr.prototype.destroy    = destroy;
    function destroy()
    {
      //this.name = null;
      //this.specified = null;
      //this.ownerElement = null;
      delete this.name;
      delete this.specified;
      delete this.ownerElement;
      this.parentMethod('destroy');
    }

    xbDOM2_Attr.prototype.getName = getName;
    function getName() 
    {
      return this.name;
    }
    
    xbDOM2_Attr.prototype.getSpecified = getSpecified;
    function getSpecified() 
    {
      return this.specified;
    }
    
    xbDOM2_Attr.prototype.getValue = getValue;
    function getValue() 
    {
      return this.value;
    }
    
    xbDOM2_Attr.prototype.getOwnerElement = getOwnerElement;
    function getOwnerElement() 
    {
      return this.ownerElement;
    }
    
    xbDOM2_Attr.prototype._setName = _setName;
    function _setName(name) 
    {
      this.nodeName = this.name = name;
    }
    
    xbDOM2_Attr.prototype._setSpecified = _setSpecified;
    function _setSpecified(specified) 
    {
      this.specified = specified;
    }
    
    xbDOM2_Attr.prototype._setOwnerElement  = _setOwnerElement;
    function _setOwnerElement(element) 
    {
      this.ownerElement = element;
    }
    
    xbDOM2_Attr.prototype.setValue = setValue;
    function setValue(value) 
    {
      this.nodeValue = this.value = value;
    }
  }
}

// xbDOM2_Element

function xbDOM2_Element(tagName, ownerDocument)
{
  _classes.defineClass('xbDOM2_Element', _prototype_func);
  
  this.init(tagName, ownerDocument);

  function _prototype_func()
  {
    xbDOM2_Element.prototype.init = init;
    function init(tagName, ownerDocument)
    {
      if (!tagName) tagName = null;
      if (!ownerDocument) ownerDocument = null;
      
      this.parentMethod('init', tagName, null, ELEMENT_NODE, ownerDocument);
      this.tagName = tagName;
      this.childNodes      =  new xbDOM2_NodeList();
      this.attributes  = this.getOwnerDocument()._createNamedNodeMap();
    }
    
    xbDOM2_Element.prototype.destroy = destroy;
    function destroy() 
    {
      //this.tagName = null;
      delete this.tagName;
      this.attributes.destroy();
      this.parentMethod('destroy');
    }

    // DOM interface
    
    xbDOM2_Element.prototype.getAttribute = getAttribute;
    function getAttribute(name) 
    {
      var attr = this.attributes.getNamedItem(name);
      if (attr)
        return attr.nodeValue;
      else
        return null;
    }
    
    xbDOM2_Element.prototype.getAttributeNS = 
    function getAttributeNS(namespaceURI, localName) 
    {
      var attr = this.attributes.getNamedItemNS(namespaceURI, localName);
      if (attr)
        return attr.nodeValue;
      else
        return null;
    }
    
    xbDOM2_Element.prototype.getAttributeNode = getAttributeNode;
    function getAttributeNode(name) 
    {
      return this.attributes.getNamedItem(name);
    }
    
    xbDOM2_Element.prototype.getAttributeNodeNS = getAttributeNodeNS;
    function getAttributeNodeNS(namespaceURI, localName) 
    {
      return this.attributes.getNamedItemNS(namespaceURI, localName);
    }
    
    xbDOM2_Element.prototype.getElementsByTagName = getElementsByTagName;
    function getElementsByTagName(tagname)
    {
      var list = this.getOwnerDocument()._createNodeList();
      var i;
      var child;
      var childList;
      
      if (this.nodeType == ELEMENT_NODE && (tagname == '*' || this.tagName == tagname))
        list.push(this);
        
      for (i = 0; i < this.childNodes.length; i++)
      {
        child = this.childNodes.item(i);
        if (child.nodeType == ELEMENT_NODE)
        {
          childList = this.childNodes.item(i).getElementsByTagName(tagname);
          list = list.concat(childList);
        }
      }
      return list;
    }
    
    xbDOM2_Element.prototype.getElementsByTagNameNS = getElementsByTagNameNS;
    function getElementsByTagNameNS(namespaceURI, localName) 
    {
      var list = this.getOwnerDocument()._createNodeList();
      var i;
      var child;
      var childList;
      
      if (this.nodeType == ELEMENT_NODE && 
        (localName    == '*' || this.localName    === localName) && 
        (namespaceURI == '*' || this.namespaceURI === namespaceURI))
      {
        list.push(this);
      }
        
      for (i = 0; i < this.childNodes.length; i++)
      {
        child = this.childNodes.item(i);
        if (child.nodeType == ELEMENT_NODE)
        {
          childList = this.childNodes.item(i).getElementsByTagNameNS(namespaceURI, localName);
          list = list.concat(childList);
        }
      }
      return list;
    }

    xbDOM2_Element.prototype.hasAttribute = hasAttribute;
    function hasAttribute(name)
    {
      return this.getAttribute(name) !== null;
    }

    xbDOM2_Element.prototype.hasAttributeNS = hasAttributeNS;
    function hasAttributeNS(namespaceURI, localName)
    {
      return this.getAttributeNS(namespaceURI, localName) !== null;
    }

    xbDOM2_Element.prototype.removeAttribute = removeAttribute;
    function removeAttribute(name) 
    {
      this.attributes.removeNamedItem(name);
    }
    
    xbDOM2_Element.prototype.removeAttributeNS = removeAttributeNS;
    function removeAttributeNS(namespaceURI, localName) 
    { 
      xbDOM_not_impl(); 
    }
    
    xbDOM2_Element.prototype.removeAttributeNode = removeAttributeNode;
    function removeAttributeNode(oldAttr) 
    {
      this.attributes.removeNamedItem(oldAttr.nodeName);
    }
    
    xbDOM2_Element.prototype.setAttribute = setAttribute;
    function setAttribute(name, value)
    {
      var attr = this.getOwnerDocument().createAttribute(name);
      attr.setValue(value);
      
      this.attributes.setNamedItem(attr);
    }
    
    xbDOM2_Element.prototype.setAttributeNS = setAttributeNS;
    function setAttributeNS(namespaceURI, localName, value) 
    { 
      xbDOM_not_impl(); 
    }
    
    xbDOM2_Element.prototype.setAttributeNode = setAttributeNode;
    function setAttributeNode(newAttr) 
    {
      this.attributes.setNamedItem(newAttr);
    }
    
    xbDOM2_Element.prototype.setAttributeNodeNS = setAttributeNodeNS;
    function setAttributeNodeNS(newAttr) 
    { 
      xbDOM_not_impl(); 
    }
    
    xbDOM2_Element.prototype.normalize = normalize;
    function normalize() 
    {
      xbDOM_not_impl();
    }
    
    xbDOM2_Element.prototype.toXML = toXML;
    function toXML()
    {
      var i;
      var s = '';
        
      s = '<' + this.nodeName;
        
      var attr;
      for (i = 0; i < this.attributes.length; i++)
      {
        attr = this.attributes.item(i);
        if (attr.nodeValue)
          s += ' ' + attr.nodeName + '=' + '"' + attr.nodeValue + '"';
      }
      s += '>';

      for (i = 0; i < this.childNodes.length; i++)
        s += this.childNodes.item(i).toXML();
            
      s += '</' + this.nodeName + '>';
            
      return s;
    }
    
    // getter/setter methods
    
    xbDOM2_Element.prototype.getTagName = getTagName;
    function getTagName() 
    {
      return this.tagName;
    }
    
    xbDOM2_Element.prototype._setTagName = _setTagName;
    function _setTagName(tagName) 
    {
      this.tagName = tagName;
    }

  }
}

// xbDOM2_Text

function xbDOM2_Text(data, ownerDocument)
{
  _classes.defineClass('xbDOM2_Text', _prototype_func);
    
  this.init(data, ownerDocument);

  function _prototype_func()
  {
    xbDOM2_Text.prototype.init = init;
    function init(data, ownerDocument)
    {
      this.parentMethod('init', data, ownerDocument);
      
      this.nodeName  = '#text';
      this.nodeType  = TEXT_NODE;
    }
    
    xbDOM2_Text.prototype.destroy = destroy;
    function destroy() 
    {
      this.parentMethod('destroy');
    }
    
    xbDOM2_Text.prototype.splitText  = splitText;
    function splitText(offset)
    {
      if (offset >= this.length || offset < 0)
        throw(new xbDOM_DOMException(INDEX_SIZE_ERR));
        
      var data    = this.getData();
      var textPrefix = data.substr(0, offset);
      var textSuffix = data.substr(offset+1);
      var newText    = this.getOwnerDocument().createTextNode(textSuffix);
      this.setData(textPrefix);
      
      this.parentNode.insertBefore(newText, this.previousSibling);
      
      return newText;
    }
    
    // convert to XML text
    
    xbDOM2_Text.prototype.toXML = toXML;
    function toXML() 
    {
      return  this.nodeValue;
    }
  }
}

// xbDOM2_Comment

function xbDOM2_Comment(data, ownerDocument)
{
  _classes.defineClass('xbDOM2_Comment', _prototype_func);
    
  this.init(data, ownerDocument);

  function _prototype_func()
  {
    xbDOM2_Comment.prototype.init = init;
    function init(data, ownerDocument)
    {
      this.parentMethod('init', data, ownerDocument);
      
      this.nodeName  = '#comment';
      this.nodeType  = COMMENT_NODE;
    }
    
    xbDOM2_Comment.prototype.destroy    = destroy
    function destroy() 
    {
      this.parentMethod('destroy');
    }
    
    // convert to XML text
    xbDOM2_Comment.prototype.toXML      = toXML;
    function toXML()  
    {
      return  '<!--' + this.nodeValue + '-->';
    }
  }
}

// xbDOM2_CDATASection

function xbDOM2_CDATASection(data, ownerDocument)
{
  _classes.defineClass('xbDOM2_CDATASection', _prototype_func);
    
  this.init(data, ownerDocument);

  function _prototype_func()
  {
    xbDOM2_CDATASection.prototype.init = init;
    function init(data, ownerDocument)
    {
      this.parentMethod('init', data, ownerDocument);
      
      this.nodeName  = '#cdata-section';
      this.nodeType  = CDATA_SECTION_NODE;
    }
    
    xbDOM2_CDATASection.prototype.destroy = destroy;
    function destroy() 
    {
      this.parentMethod('destroy');
    }
    
    // convert to XML text
    
    xbDOM2_CDATASection.prototype.toXML    = toXML;
    function toXML() 
    {
      return '<![CDATA[' + this.nodeValue + ']]>';
    }
  }
}

// xbDOM2_DocumentType

function xbDOM2_DocumentType(name, publicId, systemId, ownerDocument)
{
  _classes.defineClass('xbDOM2_DocumentType', _prototype_func);
  
  this.init(name, publicId, systemId, ownerDocument);
  
  function _prototype_func()
  {
    // constructor/destructor
    xbDOM2_DocumentType.prototype.init = init;
    function init(name, publicId, systemId, ownerDocument)
    {
      this.parentMethod('init', name, null, DOCUMENT_TYPE_NODE, ownerDocument);
      this.name    = name;
      this.entities  = null;
      this.notations  = null;
      this.publicId  = publicId;
      this.systemId  = systemId;
    }
    
    // need to override supports since the node version
    // either requires an ownerDocument or an implementation
    // newly createdDocumentTypes have neither.
    xbDOM2_DocumentType.prototype.supports = supports;
    function supports(feature, version)
    {
      if (typeof(version) == 'undefined')
        version = '1.0';
        
      if (feature.match(/XML/i) && version.match(/(1.0|2.0)/))
        return true;
        
      return false;
    }

    // getter/setter methods
    
    xbDOM2_DocumentType.prototype.getName = getName;
    function getName() 
    {
      return this.name;
    }
    
    xbDOM2_DocumentType.prototype._setName = _setName;
    function _setName(name) 
    {
      this.name = name;
    }
    
    xbDOM2_DocumentType.prototype.getEntities  = getEntities;
    function getEntities() 
    {
      return this.entities;
    }
    
    xbDOM2_DocumentType.prototype._setEntities  = _setEntities;
    function _setEntities(entities) 
    {
      return this.entities;
    }
    
    xbDOM2_DocumentType.prototype.getNotations  = getNotations;
    function getNotations() 
    {
      return this.notations;
    }
    
    xbDOM2_DocumentType.prototype._setNotations = _setNotations;
    function _setNotations(notations) 
    {
      this.notations = notations;
    }
    
    xbDOM2_DocumentType.prototype.getPublicID  = getPublicID;
    function getPublicID() 
    {
      return this.publicId;
    }
    
    xbDOM2_DocumentType.prototype._setPublicID  = _setPublicID;
    function _setPublicID(publicId) 
    {
      this.publicId = publicId;
    }
    
    xbDOM2_DocumentType.prototype.getSystemID  = getSystemID;
    function getSystemID() 
    {
      return this.systemId;
    }
    
    xbDOM2_DocumentType.prototype._setSystemID  = _setSystemID;
    function _setSystemID(systemId) 
    {
      this.systemId = systemId;
    }
    
  }
}

// xbDOM2_Notation

function xbDOM2_Notation(name, ownerDocument)
{
  _classes.defineClass('xbDOM2_Notation', _prototype_func);

  this.init(name, ownerDocument);
    
  function _prototype_func()
  {
    // constructor/destructor
    xbDOM2_Notation.prototype.init = init;
    function init(name, ownerDocument)
    {
      this.parentMethod('init', name, null, NOTATION_NODE, ownerDocument);
      this.publicId = null;
      this.systemId = null;
    }
    
    // getter/setter methods
    
    xbDOM2_Notation.prototype.getPublicId = getPublicId;
    function getPublicId() 
    {
      return this.publicId;
    }
    
    xbDOM2_Notation.prototype._setPublicId = _setPublicId;
    function _setPublicId(publicId) 
    {
      this.publicId = publicId;
    }
    
    xbDOM2_Notation.prototype.getSystemId = getSystemId;
    function getSystemId() 
    {
      return this.systemId;
    }
    
    xbDOM2_Notation.prototype._setSystemId = _setSystemId;
    function _setSystemId(systemId) 
    {
      this.systemId = systemId;
    }
  }
}

// xbDOM2_Entity

function xbDOM2_Entity(name, ownerDocument)
{
  _classes.defineClass('xbDOM2_Entity', _prototype_func);
  
  this.init(name, ownerDocument);
  
  function _prototype_func()
  {
    // constructor/destructor
    xbDOM2_Entity.prototype.init = init;
    function init(name, ownerDocument)
    {
      this.parentMethod('init', name, null, ENTITY_NODE, ownerDocument);
      this.publicId = null;
      this.systemId = null;
      this.notationName = null;
    }
    
    // getter/setter methods
    
    xbDOM2_Entity.prototype.getPublicId  = getPublicId;
    function getPublicId()   
    {
      return this.publicId;
    }
    
    xbDOM2_Entity.prototype._setPublicId = _setPublicId;
    function _setPublicId(publicId) 
    {
      this.publicId = publicId;
    }
    
    xbDOM2_Entity.prototype.getSystemId = getSystemId;
    function getSystemId() 
    {
      return this.systemId;
    }
    
    xbDOM2_Entity.prototype._setSystemId = _setSystemId;
    function _setSystemId(systemId) 
    {
      this.systemId = systemId;
    }
    
    xbDOM2_Entity.prototype.getNotationName  = getNotationName;
    function getNotationName() 
    {
      return this.notationName;
    }
    
    xbDOM2_Entity.prototype._setNotatonName  = _setNotatonName;
    function _setNotationName(notationName) 
    {
      this.notationName = notationName;
    }
  }
}


// xbDOM2_EntityReference

function xbDOM2_EntityReference(name, ownerDocument)
{
  _classes.defineClass('xbDOM2_EntityReference', _prototype_func);
  
  this.init(name, ownerDocument);
  
  function _prototype_func()
  {
    // constructor/destructor
    xbDOM2_EntityReference.prototype.init = init;
    function init(name, ownerDocument)
    {
      this.parentMethod('init', name, null, ENTITY_REFERENCE_NODE, ownerDocument);
    }

    xbDOM2_EntityReference.prototype.getName  = getName;
    function getName() 
    { 
      return this.getNodeName(); 
    }
    
    xbDOM2_EntityReference.prototype.toXML = toXML;
    function toXML()
    {
      return '&' + this.getName() + ';';
    }
  }
}

// xbDOM2_ProcessingInstruction

function xbDOM2_ProcessingInstruction(target, data, ownerDocument)
{
  _classes.defineClass('xbDOM2_ProcessingInstruction', _prototype_func);
  
  this.init(target, data, ownerDocument);
  
  function _prototype_func()
  {
    // constructor/destructor
    xbDOM2_ProcessingInstruction.prototype.init  = init;
    function init(target, data, ownerDocument)
    {
      this.parentMethod('init', target, data, PROCESSING_INSTRUCTION_NODE, ownerDocument);
      this.target = target;
      this.data = data;
    }
    
    // getter/setter methods
    
    xbDOM2_ProcessingInstruction.prototype.getTarget = getTarget;
    function getTarget() 
    {
      return this.target;
    }
    
    xbDOM2_ProcessingInstruction.prototype._setTarget  = _setTarget;
    function _setTarget(target) 
    {
      this.nodeName = this.target = target;
    }
    
    xbDOM2_ProcessingInstruction.prototype.getData = getData;
    function getData() 
    {
      return this.data;
    }
    
    xbDOM2_ProcessingInstruction.prototype.setData = setData;
    function setData(data) 
    {
      this.nodeValue = this.data = data;
    }
    
    // convert to XML text
    
    xbDOM2_ProcessingInstruction.prototype.toXML = toXML;
    function toXML()
    {
      var data = this.getData();
      var target = this.getTarget();
      var s = '<?' + target;
      if (data)
        s += ' ' + data;
      s += '?>';
      return s;
    }

  }
}

// eof: xbDOM2_core.js
