/**
 * * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Generated by Apache Flex Cross-Compiler from XML.as
 * XML
 *
 * @fileoverview
 *
 * @suppress {checkTypes|accessControls}
 */

goog.provide('XML');

goog.require('Namespace');
goog.require('QName');
goog.require('XMLList');
goog.require('org.apache.flex.utils.Language');
goog.require('XML');



/**
 * @constructor
 * @param {string=} xml
 */
XML = function(xml) {
  var self = this;
  xml = typeof xml !== 'undefined' ? xml : null;
  
  this._attributes = [];
  this._namespaces = [];
  var /** @type {Function} */ __localFn0__ = function() {
    return this;
  }
  var /** @type {Function} */ __localFn1__ = function(newValue) {
  }
  this._children = [];
  if (xml) {
    var /** @type {DOMParser} */ parser = new DOMParser();
    var /** @type {string} */ errorNS = org.apache.flex.utils.Language.string(parser.parseFromString('<', 'application/xml').getElementsByTagName("parsererror")[0].namespaceURI);
    var /** @type {Document} */ doc = parser.parseFromString(xml, "application/xml");
    if (doc.getElementsByTagNameNS(errorNS, 'parsererror').length > 0)
      throw new Error('XML parse error');
    var /** @type {Element} */ node = doc.childNodes[0];
    this._version = doc.xmlVersion;
    this._encoding = doc.xmlEncoding;
    this._name = new QName();
    this._name.prefix = node.prefix;
    this._name.uri = node.namespaceURI;
    this._name.localName = node.localName;
    XML.iterateElement(node, this);
    this.normalize();
  }
  Object.defineProperty(this, "0", {"get":__localFn0__, "set":__localFn1__, enumerable:true, configurable:true});
};


/**
 * @private
 * @type {Namespace}
 */
XML.defaultNamespace;


/**
 * @export
 * @param {*} ns
 */
XML.setDefaultNamespace = function(ns) {
  if (!ns)
    XML.defaultNamespace = null;
  else
    ns = new Namespace(ns);
};


/**
 * @export
 * @type {boolean}
 */
XML.ignoreComments = true;


/**
 * @export
 * @type {boolean}
 */
XML.ignoreProcessingInstructions = true;


/**
 * @export
 * @type {boolean}
 */
XML.ignoreWhitespace = true;


/**
 * @private
 * @type {number}
 */
XML._prettyIndent = 2;


/**
 * @private
 * @type {string}
 */
XML._indentStr = "  ";


/**
 * @private
 * @type {string}
 */
XML.INDENT_CHAR = " ";


/**
 * @export
 * @type {boolean}
 */
XML.prettyPrinting = true;


/**
 * @private
 * @param {string} value
 * @return {string}
 */
XML.escapeAttributeValue = function(value) {
  var /** @type {Array} */ outArr = [];
  var /** @type {Array} */ arr = value.split("");
  var /** @type {number} */ len = arr.length;
  for (var /** @type {number} */ i = 0; i < len; i++) {
    switch (arr[i]) {
      case "<":
        outArr[i] = "&lt;";
        break;
      case "&":
        outArr[i] = "&amp;";
        break;
      case "\n":
        outArr[i] = "&#xA;";
        break;
      case "\r":
        outArr[i] = "&#xD;";
        break;
      case "\t":
        outArr[i] = "&#x9;";
        break;
      default:
        outArr[i] = arr[i];
        break;
    }
  }
  return outArr.join("");
};


/**
 * @private
 * @param {string} value
 * @return {string}
 */
XML.escapeElementValue = function(value) {
  var /** @type {number} */ i;
  var /** @type {Array} */ outArr = [];
  var /** @type {Array} */ arr = value.split("");
  for (i = 0; i < arr.length; i++) {
    switch (arr[i]) {
      case "<":
        outArr[i] = "&lt;";
        break;
      case ">":
        outArr[i] = "&gt;";
        break;
      case "&":
        outArr[i] = "&amp;";
        break;
      default:
        outArr[i] = arr[i];
        break;
    }
  }
  return outArr.join("");
};


/**
 * @private
 * @param {Attr} att
 * @param {XML} parent
 * @return {XML}
 */
XML.insertAttribute = function(att, parent) {
  var /** @type {XML} */ xml = new XML();
  xml.setParent(parent);
  xml.setNodeKind("attribute");
  xml.setName(att.name);
  xml.setValue(att.value);
  parent.addChild(xml);
  return xml;
};


/**
 * @private
 * @param {Element} node
 * @param {XML} xml
 */
XML.iterateElement = function(node, xml) {
  var /** @type {number} */ i;
  for (i = 0; i < node.attributes.length; i++) {
    XML.insertAttribute(node.attributes[i], xml);
  }
  for (i = 0; i < node.childNodes.length; i++) {
    var /** @type {XML} */ child = XML.fromNode(node.childNodes[i]);
    xml.addChild(child);
  }
};


/**
 * returns an XML object from an existing node without the need to parse the XML.
 * The new XML object is not normalized
 * @private
 * @param {Element} node
 * @return {XML}
 */
XML.fromNode = function(node) {
  var /** @type {XML} */ xml;
  var /** @type {number} */ i;
  var /** @type {*} */ data = node.nodeValue;
  var /** @type {QName} */ qname = new QName(node.namespaceURI, node.nodeName);
  qname.prefix = node.prefix;
  switch (node.nodeType) {
    case 1:
      xml = new XML();
      xml.setNodeKind("element");
      xml.setName(qname);
      XML.iterateElement(node, xml);
      break;
    case 3:
      xml = new XML();
      xml.setNodeKind("text");
      xml.setName(qname);
      xml.setValue(data);
      break;
    case 4:
      xml = new XML();
      xml.setName(qname);
      xml.setNodeKind("text");
      data = "<![CDATA[" + data + "]]>";
      xml.setValue(data);
      break;
    case 7:
      xml = new XML();
      xml.setNodeKind("processing-instruction");
      xml.setName(qname);
      xml.setValue(data);
      break;
    case 8:
      xml = new XML();
      xml.setNodeKind("comment");
      xml.setValue(data);
      break;
    default:
      throw new TypeError("Unknown XML node type!");
      break;
  }
  return xml;
};


/**
 * @private
 * @param {Namespace} ns
 * @param {Array} arr
 * @param {boolean=} considerPrefix
 * @return {boolean}
 */
XML.namespaceInArray = function(ns, arr, considerPrefix) {
  considerPrefix = typeof considerPrefix !== 'undefined' ? considerPrefix : true;
  if (!arr)
    return false;
  var /** @type {number} */ i;
  for (i = 0; i < arr.length; i++) {
    if (ns.uri == arr[i].uri) {
      if (!considerPrefix)
        return true;
      if (ns.prefix == arr[i].prefix)
        return true;
    }
  }
  return false;
};


/**
 * @private
 * @param {string} value
 * @return {string}
 */
XML.trimXMLWhitespace = function(value) {
  return value.replace(/^\s+|\s+$/gm, '');
};


/**
 * [static] Returns an object with the following properties set to the default values: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyIndent, and prettyPrinting.
 * @asreturn 
 * 
 * @export
 * @return {Object}
 */
XML.defaultSettings = function() {
  return {ignoreComments:true, ignoreProcessingInstructions:true, ignoreWhitespace:true, prettyIndent:2, prettyPrinting:true};
};


/**
 * [static] Sets values for the following XML properties: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyIndent, and prettyPrinting.
 * @asparam rest
 * 
 * @export
 * @param {Object} value
 */
XML.setSettings = function(value) {
  if (!value)
    return;
  XML.ignoreComments = value.ignoreComments === undefined ? XML.ignoreComments : value.ignoreComments;
  XML.ignoreProcessingInstructions = value.ignoreProcessingInstructions === undefined ? XML.ignoreProcessingInstructions : value.ignoreProcessingInstructions;
  XML.ignoreWhitespace = value.ignoreWhitespace === undefined ? XML.ignoreWhitespace : value.ignoreWhitespace;
  XML.prettyIndent = value.prettyIndent === undefined ? XML.prettyIndent : value.prettyIndent;
  XML.prettyPrinting = value.prettyPrinting === undefined ? XML.prettyPrinting : value.prettyPrinting;
};


/**
 * [static] Retrieves the following properties: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyIndent, and prettyPrinting.
 * 
 * @asreturn 
 * 
 * @export
 * @return {Object}
 */
XML.settings = function() {
  return {ignoreComments:XML.ignoreComments, ignoreProcessingInstructions:XML.ignoreProcessingInstructions, ignoreWhitespace:XML.ignoreWhitespace, prettyIndent:XML.prettyIndent, prettyPrinting:XML.prettyPrinting};
};


/**
 * @private
 * @type {Array}
 */
XML.prototype._children;


/**
 * @private
 * @type {Array}
 */
XML.prototype._attributes;


/**
 * @private
 * @type {Array}
 */
XML.prototype._processingInstructions;


/**
 * @private
 * @type {XML}
 */
XML.prototype._parent;


/**
 * @private
 * @type {string}
 */
XML.prototype._value;


/**
 * @private
 * @type {string}
 */
XML.prototype._version;


/**
 * @private
 * @type {string}
 */
XML.prototype._encoding;


/**
 * @private
 * @type {Namespace}
 */
XML.prototype._appliedNamespace;


/**
 * @private
 * @type {Array}
 */
XML.prototype._namespaces;


/**
 * @asprivate
 * 
 * Similar to appendChild, but accepts all XML types (text, comment, processing-instruction, attribute, or element)
 *
 * 	
 * @export
 * @param {XML} child
 */
XML.prototype.addChild = function(child) {
  if (!child)
    return;
  child.setParent(this);
  if (child.nodeKind() == "attribute") {
    if (!this._attributes)
      this._attributes = [];
    this._attributes.push(child);
  }
  else
    this._children.push(child);
  this.normalize();
};


/**
 * Adds a namespace to the set of in-scope namespaces for the XML object.
 *
 * @asparam ns
 * @asreturn 
 * 	
 * @export
 * @param {Namespace} ns
 * @return {XML}
 */
XML.prototype.addNamespace = function(ns) {
  if (this._nodeKind == "text" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction" || this._nodeKind == "attribute")
    return this;
  if (ns.prefix === null)
    return this;
  if (ns.prefix == "" && this.name().uri == "")
    return this;
  var /** @type {Namespace} */ match = null;
  var /** @type {number} */ i;
  for (i = 0; i < this._namespaces.length; i++) {
    if (this._namespaces[i].prefix == ns.prefix) {
      match = this._namespaces[i];
      break;
    }
  }
  if (match)
    this._namespaces[i] = ns;
  else
    this._namespaces.push(ns);
  if (ns.prefix == this.name().prefix)
    this.name().prefix = null;
  for (i = 0; i < this._attributes.length; i++) {
    if (this._attributes[i].name().prefix == ns.prefix)
      this._attributes[i].name().prefix = null;
  }
  return this;
};


/**
 * Appends the given child to the end of the XML object's properties.
 *
 * @asparam child
 * @asreturn 
 * 
 * @export
 * @param {XML} child
 * @return {XML}
 */
XML.prototype.appendChild = function(child) {
  child.setParent(this);
  this._children.push(child);
  this.normalize();
  return child;
};


/**
 * Returns the XML value of the attribute that has the name matching the attributeName parameter.
 *
 * @asparam attributeName
 * @asreturn 
 * 
 * @export
 * @param {*} attributeName
 * @return {XMLList}
 */
XML.prototype.attribute = function(attributeName) {
  var /** @type {number} */ i;
  if (attributeName == "*")
    return this.attributes();
  attributeName = this.toAttributeName(attributeName);
  var /** @type {XMLList} */ list = new XMLList();
  for (i = 0; i < this._attributes.length; i++) {
    if (this._attributes[i].name().matches(attributeName))
      list.appendChild(this._attributes[i]);
  }
  list.targetObject = this;
  list.targetProperty = attributeName;
  return list;
};


/**
 * Returns a list of attribute values for the given XML object.
 *
 * @asreturn 
 * 
 * @export
 * @return {XMLList}
 */
XML.prototype.attributes = function() {
  var /** @type {number} */ i;
  var /** @type {XMLList} */ list = new XMLList();
  for (i = 0; i < this._attributes.length; i++)
    list.appendChild(this._attributes[i]);
  list.targetObject = this;
  return list;
};


/**
 * Lists the children of an XML object.
 *
 * @asparam propertyName
 * @asreturn 
 * 
 * @export
 * @param {Object} propertyName
 * @return {XMLList}
 */
XML.prototype.child = function(propertyName) {
  var /** @type {number} */ i;
  var /** @type {XMLList} */ list = new XMLList();
  if (parseInt(propertyName, 10).toString() == propertyName) {
    if (propertyName != "0")
      return null;
    list.appendChild(this);
    list.targetObject = this;
    return list;
  }
  propertyName = this.toXMLName(propertyName);
  if (propertyName.isAttribute) {
    for (i = 0; i < this._attributes.length; i++) {
      if (propertyName.matches(this._attributes[i].name()))
        list.appendChild(this._attributes[i]);
    }
  } else {
    for (i = 0; i < this._children.length; i++) {
      if (propertyName.matches(this._children[i].name()))
        list.appendChild(this._children[i]);
    }
  }
  list.targetObject = this;
  list.targetProperty = propertyName;
  return list;
};


/**
 * Identifies the zero-indexed position of this XML object within the context of its parent.
 *
 * @asreturn 
 * 
 * @export
 * @return {number}
 */
XML.prototype.childIndex = function() {
  if (!this._parent)
    return -1;
  return this._parent.getIndexOf(this);
};


/**
 * Lists the children of the XML object in the sequence in which they appear.
 *
 * @asreturn 
 * 
 * @export
 * @return {XMLList}
 */
XML.prototype.children = function() {
  var /** @type {number} */ i;
  var /** @type {XMLList} */ list = new XMLList();
  for (i = 0; i < this._children.length; i++)
    list.appendChild(this._children[i]);
  list.targetObject = this;
  return list;
};


/**
 * Lists the properties of the XML object that contain XML comments.
 *
 * @asreturn 
 * 
 * @export
 * @return {XMLList}
 */
XML.prototype.comments = function() {
  var /** @type {number} */ i;
  var /** @type {XMLList} */ list = new XMLList();
  for (i = 0; i < this._children.length; i++) {
    if (this._children[i].nodeKind() == "comment")
      list.appendChild(this._children[i]);
  }
  list.targetObject = this;
  return list;
};


/**
 * @export
 * @param {*} list
 * @return {XMLList}
 */
XML.prototype.concat = function(list) {
  if (org.apache.flex.utils.Language.is(list, XML)) {
    var /** @type {XMLList} */ newList = new XMLList();
    newList.appendChild(list);
    list = newList;
  }
  if (!org.apache.flex.utils.Language.is(list, XMLList))
    throw new TypeError("invalid type");
  var /** @type {XMLList} */ retVal = new XMLList();
  retVal.appendChild(this);
  var /** @type {XML} */ item;
  var foreachiter0_target = list;
  for (var foreachiter0 in foreachiter0_target) 
  {
  item = foreachiter0_target[foreachiter0];
  
    retVal.appendChild(item);}
  
  return retVal;
};


/**
 * Compares the XML object against the given value parameter.
 *
 * @asparam value
 * @asreturn 
 * 
 * @export
 * @param {XML} value
 * @return {boolean}
 */
XML.prototype.contains = function(value) {
  return this.equals(value);
};


/**
 * Returns a copy of the given XML object.
 * 
 * @asreturn 
 * 
 * @export
 * @return {XML}
 */
XML.prototype.copy = function() {
  var /** @type {number} */ i;
  var /** @type {XML} */ xml = new XML();
  xml.setNodeKind(this._nodeKind);
  xml.setName(this.name());
  xml.setValue(this._value);
  for (i = 0; i < this._namespaces.length; i++) {
    xml.addNamespace(new Namespace(this._namespaces[i]));
  }
  for (i = 0; i < this._attributes.length; i++)
    xml.addChild(this._attributes[i].copy());
  for (i = 0; i < this._children.length; i++)
    xml.addChild(this._children[i].copy());
  return xml;
};


/**
 * @private
 * @param {number} idx
 */
XML.prototype.deleteChildAt = function(idx) {
  if (idx < 0)
    return;
  if (idx >= this._children.length)
    return;
  var /** @type {XML} */ child = this._children[idx];
  child.setParent(null);
  this._children.splice(idx, 1);
};


/**
 * Returns all descendants (children, grandchildren, great-grandchildren, and so on) of the XML object that have the given name parameter.
 * 
 * @asparam name
 * @asreturn 
 * 
 * @export
 * @param {Object=} name
 * @return {XMLList}
 */
XML.prototype.descendants = function(name) {
  name = typeof name !== 'undefined' ? name : "*";
  var /** @type {number} */ i;
  if (!name)
    name = "*";
  name = this.toXMLName(name);
  var /** @type {XMLList} */ list = new XMLList();
  if (name.isAttribute) {
    for (i = 0; i < this._attributes.length; i++) {
      if (name.matches(this._attributes[i].name()))
        list.appendChild(this._attributes[i]);
    }
  }
  for (i = 0; i < this._children.length; i++) {
    if (this._children[i].nodeKind() == "element") {
      if (name.matches(this._children[i].name()))
        list.appendChild(this._children[i]);
      list.concat(this._children[i].descendants(name));
    }
  }
  return list;
};


/**
 * Lists the elements of an XML object. (handles E4X dot notation)
 * 
 * @asparam name
 * @asreturn 
 * 
 * @export
 * @param {Object=} name
 * @return {XMLList}
 */
XML.prototype.elements = function(name) {
  name = typeof name !== 'undefined' ? name : "*";
  if (!name)
    name = "*";
  name = this.toXMLName(name);
  var /** @type {number} */ i;
  var /** @type {XMLList} */ list = new XMLList();
  for (i = 0; i < this._children.length; i++) {
    if (this._children[i].nodeKind() == "element" && name.matches(this._children[i].name()))
      list.appendChild(this._children[i]);
  }
  list.targetObject = this;
  list.targetProperty = name;
  return list;
};


/**
 * @export
 * @param {*} xml
 * @return {boolean}
 */
XML.prototype.equals = function(xml) {
  var /** @type {number} */ i;
  if (!org.apache.flex.utils.Language.is(xml, XML))
    return false;
  if (xml.nodeKind() != this._nodeKind)
    return false;
  if (!this.name().equals(xml.name()))
    return false;
  var /** @type {Array} */ selfAttrs = this.getAttributeArray();
  var /** @type {Array} */ xmlAttrs = xml.getAttributeArray();
  if (selfAttrs.length != xmlAttrs.length)
    return false;
  if (this.getValue() != xml.getValue())
    return false;
  for (i = 0; i < selfAttrs.length; i++) {
    if (!xml.hasAttribute(selfAttrs[i]))
      return false;
  }
  var /** @type {Array} */ selfChldrn = this.getChildrenArray();
  var /** @type {Array} */ xmlChildren = xml.getChildrenArray();
  if (selfChldrn.length != xmlChildren.length)
    return false;
  for (i = 0; i < selfChldrn.length; i++) {
    if (!selfChldrn[i].equals(xmlChildren[i]))
      return false;
  }
  return true;
};


/**
 * @export
 * @param {*} nameOrXML
 * @param {string=} value
 * @return {boolean}
 */
XML.prototype.hasAttribute = function(nameOrXML, value) {
  value = typeof value !== 'undefined' ? value : null;
  if (!this._attributes)
    return false;
  var /** @type {QName} */ name;
  if (org.apache.flex.utils.Language.is(nameOrXML, XML)) {
    name = nameOrXML.name();
    value = org.apache.flex.utils.Language.string(nameOrXML.getValue());
  } else {
    name = new QName(nameOrXML);
  }
  var /** @type {number} */ i;
  for (i = 0; i < this._attributes.length; i++) {
    if (name.matches(this._attributes[i].name())) {
      if (!value)
        return true;
      return value == this._attributes[i].getValue();
    }
  }
  return false;
};


/**
 * @private
 * @param {Array} namespaces
 * @return {Array}
 */
XML.prototype.getAncestorNamespaces = function(namespaces) {
  namespaces = namespaces.slice();
  var /** @type {number} */ nsIdx;
  var /** @type {number} */ pIdx;
  if (this._parent) {
    var /** @type {Array} */ parentNS = this._parent.inScopeNamespaces();
    var /** @type {number} */ len = parentNS.length;
    for (pIdx = 0; pIdx < len; pIdx++) {
      var /** @type {Namespace} */ curNS = parentNS[pIdx];
      var /** @type {boolean} */ doInsert = true;
      for (nsIdx = 0; nsIdx < namespaces.length; nsIdx++) {
        if (curNS.uri == namespaces[nsIdx].uri && curNS.prefix == namespaces[nsIdx].prefix) {
          doInsert = false;
          break;
        }
      }
      if (doInsert)
        namespaces.push(curNS);
    }
    namespaces = this._parent.getAncestorNamespaces(namespaces);
  }
  return namespaces;
};


/**
 * @export
 * @return {Array}
 */
XML.prototype.getAttributeArray = function() {
  return this._attributes ? this._attributes.slice() : [];
};


/**
 * @export
 * @return {Array}
 */
XML.prototype.getChildrenArray = function() {
  return this._children ? this._children.slice() : [];
};


/**
 * @export
 * @param {XML} elem
 * @return {number}
 */
XML.prototype.getIndexOf = function(elem) {
  return this._children.indexOf(elem);
};


/**
 * @private
 * @param {string} prefix
 * @return {string}
 */
XML.prototype.getURI = function(prefix) {
  var /** @type {number} */ i;
  var /** @type {Array} */ namespaces = this.getAncestorNamespaces(this._namespaces);
  for (i = 0; i < namespaces.length; i++) {
    if (namespaces[i].prefix == prefix)
      return namespaces[i].uri;
  }
  return "";
};


/**
 * @export
 * @return {string}
 */
XML.prototype.getValue = function() {
  return this._value;
};


/**
 * Checks to see whether the XML object contains complex content.
 * 
 * @asreturn 
 * 
 * @export
 * @return {boolean}
 */
XML.prototype.hasComplexContent = function() {
  if (this._nodeKind == "attribute" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction" || this._nodeKind == "text")
    return false;
  var /** @type {number} */ i;
  for (i = 0; i < this._children.length; i++) {
    if (this._children[i].nodeKind() == "element")
      return true;
  }
  return false;
};


/**
 * @export
 * @override
 */
XML.prototype.hasOwnProperty = function(p) {
  if (parseInt(p, 10).toString() == p)
    return p == "0";
  var /** @type {QName} */ name = this.toXMLName(p);
  var /** @type {number} */ i;
  for (i = 0; i < this._attributes.length; i++) {
    if (this._attributes[i].name().matches(name))
      return true;
  }
  for (i = 0; i < this._children.length; i++) {
    if (this._children[i].nodeKind() != "element")
      continue;
    if (this._children[i].name().matches(name))
      return true;
  }
  return false;
};


/**
 * Checks to see whether the XML object contains simple content.
 * 
 * @asreturn 
 * 
 * @export
 * @return {boolean}
 */
XML.prototype.hasSimpleContent = function() {
  if (this._nodeKind == "comment" || this._nodeKind == "processing-instruction")
    return false;
  var /** @type {number} */ i;
  for (i = 0; i < this._children.length; i++) {
    if (this._children[i].nodeKind() == "element")
      return false;
  }
  return true;
};


/**
 * Lists the namespaces for the XML object, based on the object's parent.
 * 
 * @asreturn 
 * 
 * @export
 * @return {Array}
 */
XML.prototype.inScopeNamespaces = function() {
  return this._namespaces.slice();
};


/**
 * @private
 * @param {XML} child
 * @param {number} idx
 */
XML.prototype.insertChildAt = function(child, idx) {
  if (this._nodeKind == "text" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction" || this._nodeKind == "attribute")
    return;
  if (!child)
    return;
  var /** @type {XML} */ parent = child.parent();
  if (parent)
    parent.removeChild(child);
  child.setParent(this);
  this._children.splice(idx, 0, child);
};


/**
 * Inserts the given child2 parameter after the child1 parameter in this XML object and returns the resulting object.
 * 
 * @asparam child1
 * @asparam child2
 * @asreturn 
 * 
 * @export
 * @param {XML} child1
 * @param {XML} child2
 * @return {XML}
 */
XML.prototype.insertChildAfter = function(child1, child2) {
  if (this._nodeKind == "text" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction" || this._nodeKind == "attribute")
    return null;
  if (!child1) {
    this.insertChildAt(child2, 0);
    return child2;
  }
  var /** @type {number} */ idx = Number(this._children.indexOf(child1));
  if (idx >= 0) {
    this.insertChildAt(child2, idx + 1);
  }
  return child2;
};


/**
 * Inserts the given child2 parameter before the child1 parameter in this XML object and returns the resulting object.
 * 
 * @asparam child1
 * @asparam child2
 * @asreturn 
 * 
 * @export
 * @param {XML} child1
 * @param {XML} child2
 * @return {XML}
 */
XML.prototype.insertChildBefore = function(child1, child2) {
  if (this._nodeKind == "text" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction" || this._nodeKind == "attribute")
    return null;
  if (!child1) {
    this.insertChildAt(child2, this._children.length);
    return child2;
  }
  var /** @type {number} */ idx = Number(this._children.indexOf(child1));
  if (idx >= 0) {
    this.insertChildAt(child2, idx);
  }
  return child2;
};


/**
 * For XML objects, this method always returns the integer 1.
 * 
 * @asreturn 
 * 
 * @export
 * @return {number}
 */
XML.prototype.length = function() {
  return 1;
};


/**
 * Gives the local name portion of the qualified name of the XML object.
 * 
 * @asreturn 
 * 
 * @export
 * @return {Object}
 */
XML.prototype.localName = function() {
  return this.name().localName;
};


/**
 * @private
 * @type {QName}
 */
XML.prototype._name;


/**
 * Gives the qualified name for the XML object.
 * 
 * @asreturn 
 * 
 * @export
 * @return {Object}
 */
XML.prototype.name = function() {
  if (!this._name)
    this._name = new QName();
  return this._name;
};


/**
 * If no parameter is provided, gives the namespace associated with the qualified name of this XML object.
 * 
 * @asparam prefix
 * @asreturn 
 * 
 * @export
 * @param {string=} prefix
 * @return {*}
 */
XML.prototype.namespace = function(prefix) {
  prefix = typeof prefix !== 'undefined' ? prefix : null;
  var /** @type {number} */ i;
  if (prefix) {
    for (i = 0; i < this._namespaces.length; i++) {
      if (this._namespaces[i].prefix == prefix)
        return this._namespaces[i];
    }
    if (this._parent)
      return this._parent.namespace(prefix);
    return null;
  }
  if (this._nodeKind == "text" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction")
    return null;
  return this.name().getNamespace(this.namespaceDeclarations());
};


/**
 * Lists namespace declarations associated with the XML object in the context of its parent.
 * 
 * @asreturn 
 * 
 * @export
 * @return {Array}
 */
XML.prototype.namespaceDeclarations = function() {
  var /** @type {number} */ i;
  var /** @type {Array} */ retVal = [];
  if (this._nodeKind == "text" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction" || this._nodeKind == "attribute")
    return retVal;
  var /** @type {Array} */ declaredNS = this._namespaces.slice();
  var /** @type {XML} */ parent = this._parent;
  while (parent) {
    var /** @type {Array} */ parentNS = parent.inScopeNamespaces();
    var /** @type {number} */ idx;
    var /** @type {number} */ pIdx;
    for (pIdx = 0; i < parentNS.length; pIdx++) {
      var /** @type {string} */ uri = org.apache.flex.utils.Language.string(parentNS[pIdx].uri);
      var /** @type {string} */ prefix = org.apache.flex.utils.Language.string(parentNS[pIdx].prefix);
      for (idx = 0; i < declaredNS.length; idx++) {
        if (declaredNS[idx].uri == uri && declaredNS[idx].prefix == prefix) {
          declaredNS.push(parentNS[pIdx]);
          break;
        }
      }
    }
    parent = parent.parent();
  }
  return declaredNS;
};


/**
 * @private
 * @type {string}
 */
XML.prototype._nodeKind = "element";


/**
 * Specifies the type of node: text, comment, processing-instruction, attribute, or element.
 * @asreturn 
 * 
 * @export
 * @return {string}
 */
XML.prototype.nodeKind = function() {
  return this._nodeKind;
};


/**
 * For the XML object and all descendant XML objects, merges adjacent text nodes and eliminates empty text nodes.
 * 
 * @asreturn 
 * 
 * @export
 * @return {XML}
 */
XML.prototype.normalize = function() {
  var /** @type {number} */ len = this._children.length - 1;
  var /** @type {XML} */ lastChild;
  for (var /** @type {number} */ i = len; i >= 0; i--) {
    var /** @type {XML} */ child = this._children[i];
    if (child.nodeKind() == "element") {
      child.normalize();
    } else if (child.nodeKind() == "text") {
      if (lastChild && lastChild.nodeKind() == "text") {
        child.setValue(child.text() + lastChild.text());
        this.deleteChildAt(i + 1);
      }
      if (!child.text())
        this.deleteChildAt(i);
    }
    lastChild = child;
  }
  return this;
};


/**
 * Returns the parent of the XML object.
 * 
 * @asreturn 
 * 
 * @export
 * @return {*}
 */
XML.prototype.parent = function() {
  return this._parent;
};


/**
 * @export
 * @param {*} rightHand
 * @return {*}
 */
XML.prototype.plus = function(rightHand) {
  var /** @type {XMLList} */ list = new XMLList();
  list.appendChild(this);
  return list.plus(rightHand);
};


/**
 * Inserts the provided child object into the XML element before any existing XML properties for that element.
 * @asparam value
 * @asreturn 
 * 
 * @export
 * @param {XML} child
 * @return {XML}
 */
XML.prototype.prependChild = function(child) {
  child.setParent(this);
  this._children.unshift(child);
  return child;
};


/**
 * If a name parameter is provided, lists all the children of the XML object that contain processing instructions with that name.
 * 
 * @asparam name
 * @asreturn 
 * 
 * @export
 * @param {string=} name
 * @return {XMLList}
 */
XML.prototype.processingInstructions = function(name) {
  name = typeof name !== 'undefined' ? name : "*";
  var /** @type {number} */ i;
  var /** @type {XMLList} */ list = new XMLList();
  for (i = 0; i < this._children.length; i++) {
    if (this._children[i].nodeKind() == "processing-instruction")
      list.appendChild(this._children[i]);
  }
  list.targetObject = this;
  return list;
};


/**
 * Removes the given chid for this object and returns the removed child.
 * 
 * @asparam child
 * @asreturn 
 * 
 * @export
 * @param {XML} child
 * @return {boolean}
 */
XML.prototype.removeChild = function(child) {
  var /** @type {number} */ i;
  var /** @type {XML} */ removed;
  if (!child)
    return false;
  if (!this._attributes)
    return false;
  if (!org.apache.flex.utils.Language.is(child, XML))
    return this.removeChildByName(child);
  if (child.nodeKind() == "attribute") {
    for (i = 0; i < this._attributes.length; i++) {
      if (child.equals(this._attributes[i])) {
        removed = this._attributes[i];
        removed.setParent(null);
        this._attributes.splice(i, 1);
        return true;
      }
    }
  }
  var /** @type {number} */ idx = Number(this._children.indexOf(child));
  if (idx < 0)
    return false;
  removed = this._children.splice(idx, 1);
  child.setParent(null);
  return removed;
};


/**
 * @private
 * @param {*} name
 * @return {boolean}
 */
XML.prototype.removeChildByName = function(name) {
  var /** @type {number} */ i;
  name = this.toXMLName(name);
  var /** @type {XML} */ child = null;
  var /** @type {boolean} */ removedItem = false;
  if (name.isAttribute) {
    if (!this._attributes)
      return false;
    for (i = this._attributes.length - 1; i >= 0; i--) {
      if (this._attributes[i].name().matches(name)) {
        child = this._attributes[i];
        child.setParent(null);
        this._attributes.splice(i, 1);
        removedItem = true;
      }
    }
    return removedItem;
  }
  if (!this._children)
    return false;
  for (i = this._children.length - 1; i >= 0; i--) {
    if (this._children[i].name().matches(name)) {
      child = this._children[i];
      child.setParent(null);
      this._children.splice(i, 1);
      removedItem = true;
    }
  }
  return removedItem;
};


/**
 * @export
 * @param {number} index
 */
XML.prototype.removeChildAt = function(index) {
  throw new Error("Cannot call delete on XML");
};


/**
 * Removes the given namespace for this object and all descendants.
 * 
 * @asparam ns
 * @asreturn 
 * 
 * @export
 * @param {*} ns
 * @return {XML}
 */
XML.prototype.removeNamespace = function(ns) {
  var /** @type {number} */ i;
  if (this._nodeKind == "text" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction" || this._nodeKind == "attribute")
    return this;
  if (!org.apache.flex.utils.Language.is(ns, Namespace))
    ns = new Namespace(ns);
  if (ns == this.name().getNamespace(this._namespaces))
    return this;
  for (i = 0; i < this._attributes.length; i++) {
    if (ns == this._attributes[i].name().getNamespace(this._namespaces))
      return this;
  }
  for (i = this._namespaces.length - 1; i >= 0; i--) {
    if (this._namespaces[i].uri == ns.uri && this._namespaces[i].prefix == ns.prefix)
      this._namespaces.splice(i, 1);
    else if (ns.prefix == null && this._namespaces[i].uri == ns.uri)
      this._namespaces.splice(i, 1);
  }
  for (i = 0; i < this._children.length; i++) {
    if (this._children[i].nodeKind() == "element")
      this._children[i].removeNamespace(ns);
  }
  return this;
};


/**
 * Replaces the properties specified by the propertyName parameter with the given value parameter.
 * 
 * @asparam propertyName
 * @asparam value
 * @asreturn 
 * 
 * @export
 * @param {Object} propertyName
 * @param {*} value
 * @return {XML}
 */
XML.prototype.replace = function(propertyName, value) {
  if (this._nodeKind == "text" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction" || this._nodeKind == "attribute")
    return this;
  if (value === null || value === undefined)
    return this;
  if (org.apache.flex.utils.Language.is(value, XML) || org.apache.flex.utils.Language.is(value, XMLList))
    value = value.copy();
  else
    value = value.toString();
  return null;
};


/**
 * @export
 * @param {number} idx
 * @param {*} v
 */
XML.prototype.replaceChildAt = function(idx, v) {
  if (this._nodeKind == "text" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction" || this._nodeKind == "attribute")
    return;
  if (idx > this._children.length)
    idx = Number(this._children.length);
  if (org.apache.flex.utils.Language.is(v, XML) && v.nodeKind() != "attribute") {
    if (v.nodeKind() == "element" && (v == this || this.isAncestor(v)))
      throw new TypeError("cannot assign parent xml as child");
    v.setParent(this);
    if (this._children[idx])
      this.removeChild(this._children[idx]);
    this.insertChildAt(v, idx);
  } else if (org.apache.flex.utils.Language.is(v, XMLList)) {
    if (this._children[idx])
      this._children[idx].setParent(null);
    var /** @type {number} */ len = Number(v.length());
    v[0].setParent(this);
    this._children[idx] = v[0];
    var /** @type {number} */ listIdx = 1;
    var /** @type {XML} */ chld = v[0];
    while (listIdx < len) {
      chld = v[listIdx];
      this.insertChildAt(chld, idx + listIdx);
      listIdx++;
    }
  } else {
  }
};


/**
 * @private
 * @param {XML} xml
 * @return {boolean}
 */
XML.prototype.isAncestor = function(xml) {
  var /** @type {XML} */ p = this.parent();
  while (p) {
    if (p == xml)
      return true;
    p = p.parent();
  }
  return false;
};


/**
 * @export
 * @param {*} attr
 * @param {string} value
 */
XML.prototype.setAttribute = function(attr, value) {
  var /** @type {number} */ i;
  if (!this._attributes)
    this._attributes = [];
  if (org.apache.flex.utils.Language.is(attr, XML)) {
    if (attr.nodeKind() == "attribute") {
      for (i = 0; i < this._attributes.length; i++) {
        if (this._attributes[i].name().equals(attr.name())) {
          this._attributes[i].setValue(value);
          return;
        }
      }
      if (value)
        attr.setValue(value);
      this.addChild(attr);
    }
    return;
  }
  if (attr.indexOf("xmlns") == 0) {
    var /** @type {Namespace} */ ns = new Namespace(value.toString());
    if (attr.indexOf("xmlns:") == 0)
      ns.prefix = org.apache.flex.utils.Language.string(attr.split(":")[1]);
    this.addNamespace(ns);
  } else {
    var /** @type {QName} */ qname = this.toAttributeName(attr);
    var /** @type {XML} */ attrXML = new XML();
    attrXML.setNodeKind("attribute");
    attrXML.setName(this.toAttributeName(attr));
    attrXML.setValue(value);
    for (i = 0; i < this._attributes.length; i++) {
      if (this._attributes[i].name().equals(attrXML.name())) {
        this._attributes[i].setValue(value);
        return;
      }
    }
    this.addChild(attrXML);
  }
};


/**
 * Replaces the child properties of the XML object with the specified name with the specified XML or XMLList.
 * This is primarily used to support dot notation assignment of XML.
 * 
 * @asparam value
 * @asreturn 
 * 
 * @export
 * @param {*} elementName
 * @param {Object} elements
 */
XML.prototype.setChild = function(elementName, elements) {
  var /** @type {number} */ i;
  var /** @type {number} */ len;
  var /** @type {XML} */ chld;
  if (org.apache.flex.utils.Language.is(elements, XML)) {
    var /** @type {XMLList} */ list = new XMLList();
    list[0] = elements;
    elements = list;
  }
  if (org.apache.flex.utils.Language.is(elements, XMLList)) {
    var /** @type {XMLList} */ chldrn = this.child(elementName);
    var /** @type {number} */ childIdx = this.children().length() - 1;
    if (chldrn.length())
      childIdx = chldrn[0].childIndex() - 1;
    len = chldrn.length() - 1;
    for (i = len; i >= 0; i--) {
      this.removeChild(chldrn[i]);
    }
    var /** @type {XML} */ curChild = this._children[childIdx];
    len = Number(elements.length());
    for (i = 0; i < len; i++) {
      chld = elements[i];
      if (!curChild) {
        if (childIdx < 0)
          curChild = this.prependChild(chld);
        else
          curChild = this.appendChild(chld);
      } else {
        curChild = this.insertChildAfter(curChild, chld);
      }
    }
  }
};


/**
 * Replaces the child properties of the XML object with the specified set of XML properties, provided in the value parameter.
 * 
 * @asparam value
 * @asreturn 
 * 
 * @export
 * @param {Object} value
 * @return {XML}
 */
XML.prototype.setChildren = function(value) {
  var /** @type {number} */ i;
  var /** @type {number} */ len;
  var /** @type {XML} */ chld;
  if (org.apache.flex.utils.Language.is(value, XML)) {
    var /** @type {XMLList} */ list = new XMLList();
    list[0] = value;
    value = list;
  }
  if (org.apache.flex.utils.Language.is(value, XMLList)) {
    var /** @type {XMLList} */ chldrn = this.children();
    var /** @type {number} */ childIdx = chldrn.length() - 1;
    if (chldrn.length())
      childIdx = Number(chldrn[0].childIndex());
    len = chldrn.length() - 1;
    for (i = len; i >= 0; i--) {
      this.removeChild(chldrn[i]);
    }
    var /** @type {XML} */ curChild = this._children[childIdx];
    len = Number(value.length());
    for (i = 0; i < len; i++) {
      chld = value[i];
      if (!curChild) {
        curChild = this.appendChild(chld);
      } else {
        curChild = this.insertChildAfter(curChild, chld);
      }
    }
  }
  return this;
};


/**
 * Changes the local name of the XML object to the given name parameter.
 * 
 * @asparam name
 * 
 * @export
 * @param {string} name
 */
XML.prototype.setLocalName = function(name) {
  if (!this._name)
    this._name = new QName();
  this._name.localName = name;
};


/**
 * Sets the name of the XML object to the given qualified name or attribute name.
 * 
 * @asparam name
 * 
 * @export
 * @param {*} name
 */
XML.prototype.setName = function(name) {
  if (org.apache.flex.utils.Language.is(name, QName))
    this._name = name;
  else
    this._name = new QName(name);
};


/**
 * Sets the namespace associated with the XML object.
 * 
 * @asparam ns
 * 
 * @export
 * @param {Object} ns
 */
XML.prototype.setNamespace = function(ns) {
  if (this._nodeKind == "text" || this._nodeKind == "comment" || this._nodeKind == "processing-instruction")
    return;
  var /** @type {Namespace} */ ns2 = new Namespace(ns);
  this._name = new QName(ns2, this.name());
  if (this._nodeKind == "attribute") {
    this._name.isAttribute = true;
    if (this._parent == null)
      return;
    this._parent.addNamespace(ns2);
  }
  if (this._nodeKind == "element")
    this.addNamespace(ns2);
};


/**
 * @asprivate
 * 
 * @export
 * @param {string} value
 */
XML.prototype.setNodeKind = function(value) {
  this._nodeKind = value;
};


/**
 * @export
 * @param {XML} parent
 */
XML.prototype.setParent = function(parent) {
  if (parent == this._parent)
    return;
  var /** @type {XML} */ oldParent = this._parent;
  this._parent = parent;
  if (oldParent)
    oldParent.removeChild(this);
};


/**
 * @export
 * @param {string} value
 */
XML.prototype.setValue = function(value) {
  this._value = value;
};


/**
 * Returns an XMLList object of all XML properties of the XML object that represent XML text nodes.
 * 
 * @asreturn 
 * 
 * @export
 * @return {XMLList}
 */
XML.prototype.text = function() {
  var /** @type {XMLList} */ list = new XMLList();
  var /** @type {number} */ i;
  for (i = 0; i < this._children.length; i++) {
    if (this._children[i].nodeKind() == "text")
      list.appendChild(this._attributes[i]);
  }
  list.targetObject = this;
  return list;
};


/**
 * Returns a string representation of the XML object.
 * 
 * @asreturn 
 * 
 * @export
 * @return {string}
 */
XML.prototype.toString = function() {
  var /** @type {number} */ i;
  if (this._nodeKind == "text" || this._nodeKind == "attribute")
    return this._value;
  if (this._nodeKind == "comment")
    return "";
  if (this._nodeKind == "processing-instruction")
    return "";
  if (this.hasSimpleContent()) {
    var /** @type {string} */ s = "";
    for (i = 0; i < this._children.length; i++) {
      if (this._children[i].nodeKind() == "comment" || this._children[i].nodeKind() == "processing-instruction")
        continue;
      s = s + this._children[i].toString();
    }
    return s;
  }
  return this.toXMLString();
};


/**
 * @private
 * @param {*} name
 * @return {QName}
 */
XML.prototype.toAttributeName = function(name) {
  var /** @type {QName} */ qname;
  if (org.apache.flex.utils.Language.is(!name, QName)) {
    name = name.toString();
    if (name.indexOf("@") > -1)
      name = name.substring(name.indexOf("@"));
  }
  qname = this.toXMLName(name);
  qname.isAttribute = true;
  return qname;
};


/**
 * @private
 * @param {*} name
 * @return {QName}
 */
XML.prototype.toXMLName = function(name) {
  var /** @type {QName} */ qname;
  if (name.toString().indexOf("@") > -1)
    return this.toAttributeName(name);
  if (parseInt(name, 10).toString() == name)
    throw new TypeError("invalid element name");
  if (org.apache.flex.utils.Language.is(!name, QName)) {
    name = name.toString();
    if (name.indexOf(":") >= 0) {
      qname = new QName();
      qname.prefix = org.apache.flex.utils.Language.string(name.substring(0, name.indexOf(":")));
      qname.localName = org.apache.flex.utils.Language.string(name.substring(name.lastIndexOf(":") + 1));
      qname.uri = this.getURI(qname.prefix);
    } else {
      qname = new QName(name());
      if (!qname.uri && XML.defaultNamespace) {
        qname = new QName(XML.defaultNamespace);
      }
      qname.localName = org.apache.flex.utils.Language.string(name);
    }
  } else {
    qname = new QName(name);
  }
  return qname;
};


/**
 * Returns a string representation of the XML object.
 * 
 * @asreturn 
 * 
 * @export
 * @param {number=} indentLevel
 * @param {Array=} ancestors
 * @return {string}
 */
XML.prototype.toXMLString = function(indentLevel, ancestors) {
  indentLevel = typeof indentLevel !== 'undefined' ? indentLevel : 0;
  ancestors = typeof ancestors !== 'undefined' ? ancestors : null;
  var /** @type {number} */ i;
  var /** @type {Namespace} */ ns;
  var /** @type {Array} */ strArr = [];
  indentLevel = Number(isNaN(indentLevel) ? 0 : indentLevel);
  var /** @type {Array} */ indentArr = [];
  for (i = 0; i < indentLevel; i++)
    indentArr.push(XML._indentStr);
  var /** @type {string} */ indent = indentArr.join("");
  if (this.nodeKind() == "text") {
    if (XML.prettyPrinting) {
      var /** @type {string} */ v = XML.trimXMLWhitespace(this._value);
      return indent + XML.escapeElementValue(v);
    }
    return XML.escapeElementValue(this._value);
  }
  if (this.nodeKind() == "attribute")
    return indent + XML.escapeAttributeValue(this._value);
  if (this.nodeKind() == "comment")
    return indent + "<!--" + this._value + "-->";
  if (this.nodeKind() == "processing-instruction")
    return indent + "<?" + this.name().localName + " " + this._value + "?>";
  if (!ancestors)
    ancestors = [];
  var /** @type {Array} */ declarations = [];
  for (i = 0; i < this._namespaces.length; i++) {
    if (!XML.namespaceInArray(this._namespaces[i], ancestors))
      declarations.push(new Namespace(this._namespaces[i]));
  }
  for (i = 0; i < this._attributes.length; i++) {
    ns = new Namespace(this._attributes[i].name().getNamespace(ancestors.concat(declarations)));
    if (ns.prefix === null) {
      ns.prefix = "";
      declarations.push(ns);
    }
  }
  ns = new Namespace(this.name().getNamespace(ancestors.concat(declarations)));
  if (ns.prefix === null) {
    ns.prefix = "";
    declarations.push(ns);
  }
  if (XML.prettyPrinting) {
    strArr.push(new Array(indentLevel).join(' '));
  }
  strArr.push("<");
  if (ns.prefix)
    strArr.push(ns.prefix + ":");
  strArr.push(this.name().localName);
  for (i = 0; i < declarations.length; i++) {
    var /** @type {string} */ decVal = XML.escapeAttributeValue(declarations[i].uri);
    if (decVal) {
      strArr.push(" xmlns");
      if (declarations[i].prefix) {
        strArr.push(":");
        strArr.push(declarations[i].prefix);
      }
      strArr.push('="');
      strArr.push(decVal);
      strArr.push('"');
    }
  }
  for (i = 0; i < this._attributes.length; i++) {
    strArr.push(" ");
    var /** @type {QName} */ aName = this._attributes[i].name();
    var /** @type {Namespace} */ ans = aName.getNamespace(ancestors.concat(declarations));
    if (ans.prefix) {
      strArr.push(ans.prefix);
      strArr.push(":");
    }
    strArr.push(aName.localName);
    strArr.push('="');
    strArr.push(XML.escapeAttributeValue(this._attributes[i].getValue()));
    strArr.push('"');
  }
  if (this._children.length == 0) {
    strArr.push("/>");
    return strArr.join("");
  }
  strArr.push(">");
  var /** @type {boolean} */ indentChildren = this._children.length > 1 || (this._children.length == 1 && this._children[0].nodeKind() != "text");
  var /** @type {number} */ nextIndentLevel;
  if (XML.prettyPrinting && indentChildren)
    nextIndentLevel = Number(indentLevel + XML.prettyIndent);
  else
    nextIndentLevel = 0;
  for (i = 0; i < this._children.length; i++) {
    if (XML.prettyPrinting && indentChildren)
      strArr.push("\n");
    strArr.push(this._children[i].toXMLString(nextIndentLevel, ancestors.concat(declarations)));
  }
  if (XML.prettyPrinting && indentChildren) {
    strArr.push("\n");
    strArr.push(new Array(indentLevel + 1).join(' '));
  }
  strArr.push("</");
  if (ns.prefix) {
    strArr.push(ns.prefix);
    strArr.push(":");
  }
  strArr.push(this.name().localName);
  strArr.push(">");
  return strArr.join("");
};


/**
 * Returns the XML object.
 * 
 * @asreturn 
 * 
 * @export
 * @override
 */
XML.prototype.valueOf = function() {
  return this;
};Object.defineProperties(XML, /** @lends {XML} */ {
/** @expose */
prettyIndent: {
get: function() {
  return XML._prettyIndent;
},
set: function(value) {
  XML._prettyIndent = value;
  XML._indentStr = "";
  for (var /** @type {number} */ i = 0; i < value; i++) {
    XML._indentStr = XML._indentStr + XML.INDENT_CHAR;
  }
}}}
);


/**
 * Metadata
 *
 * @type {Object.<string, Array.<Object>>}
 */
XML.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'XML', qName: 'XML'}] };


/**
 * Prevent renaming of class. Needed for reflection.
 */
goog.exportSymbol('XML', XML);



/**
 * Reflection
 *
 * @return {Object.<string, Function>}
 */
XML.prototype.FLEXJS_REFLECTION_INFO = function () {
  return {
    variables: function () {
      return {
      };
    },
    accessors: function () {
      return {
      };
    },
    methods: function () {
      return {
        'XML': { type: '', declaredBy: 'XML'},
        'addChild': { type: 'void', declaredBy: 'XML'},
        'addNamespace': { type: 'XML', declaredBy: 'XML'},
        'appendChild': { type: 'XML', declaredBy: 'XML'},
        'attribute': { type: 'XMLList', declaredBy: 'XML'},
        'attributes': { type: 'XMLList', declaredBy: 'XML'},
        'child': { type: 'XMLList', declaredBy: 'XML'},
        'childIndex': { type: 'int', declaredBy: 'XML'},
        'children': { type: 'XMLList', declaredBy: 'XML'},
        'comments': { type: 'XMLList', declaredBy: 'XML'},
        'concat': { type: 'XMLList', declaredBy: 'XML'},
        'contains': { type: 'Boolean', declaredBy: 'XML'},
        'copy': { type: 'XML', declaredBy: 'XML'},
        'descendants': { type: 'XMLList', declaredBy: 'XML'},
        'elements': { type: 'XMLList', declaredBy: 'XML'},
        'equals': { type: 'Boolean', declaredBy: 'XML'},
        'hasAttribute': { type: 'Boolean', declaredBy: 'XML'},
        'getAttributeArray': { type: 'Array', declaredBy: 'XML'},
        'getChildrenArray': { type: 'Array', declaredBy: 'XML'},
        'getIndexOf': { type: 'int', declaredBy: 'XML'},
        'getValue': { type: 'String', declaredBy: 'XML'},
        'hasComplexContent': { type: 'Boolean', declaredBy: 'XML'},
        'hasOwnProperty': { type: 'Boolean', declaredBy: 'XML'},
        'hasSimpleContent': { type: 'Boolean', declaredBy: 'XML'},
        'inScopeNamespaces': { type: 'Array', declaredBy: 'XML'},
        'insertChildAfter': { type: 'XML', declaredBy: 'XML'},
        'insertChildBefore': { type: 'XML', declaredBy: 'XML'},
        'length': { type: 'int', declaredBy: 'XML'},
        'localName': { type: 'Object', declaredBy: 'XML'},
        'name': { type: 'Object', declaredBy: 'XML'},
        'namespace': { type: '*', declaredBy: 'XML'},
        'namespaceDeclarations': { type: 'Array', declaredBy: 'XML'},
        'nodeKind': { type: 'String', declaredBy: 'XML'},
        'normalize': { type: 'XML', declaredBy: 'XML'},
        'parent': { type: '*', declaredBy: 'XML'},
        'plus': { type: '*', declaredBy: 'XML'},
        'prependChild': { type: 'XML', declaredBy: 'XML'},
        'processingInstructions': { type: 'XMLList', declaredBy: 'XML'},
        'removeChild': { type: 'Boolean', declaredBy: 'XML'},
        'removeChildAt': { type: 'void', declaredBy: 'XML'},
        'removeNamespace': { type: 'XML', declaredBy: 'XML'},
        'replace': { type: 'XML', declaredBy: 'XML'},
        'replaceChildAt': { type: 'void', declaredBy: 'XML'},
        'setAttribute': { type: 'void', declaredBy: 'XML'},
        'setChild': { type: 'void', declaredBy: 'XML'},
        'setChildren': { type: 'XML', declaredBy: 'XML'},
        'setLocalName': { type: 'void', declaredBy: 'XML'},
        'setName': { type: 'void', declaredBy: 'XML'},
        'setNamespace': { type: 'void', declaredBy: 'XML'},
        'setNodeKind': { type: 'void', declaredBy: 'XML'},
        'setParent': { type: 'void', declaredBy: 'XML'},
        'setValue': { type: 'void', declaredBy: 'XML'},
        'text': { type: 'XMLList', declaredBy: 'XML'},
        'toString': { type: 'String', declaredBy: 'XML'},
        'toXMLString': { type: 'String', declaredBy: 'XML'},
        'valueOf': { type: '*', declaredBy: 'XML'}
      };
    }
  };
};