http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a487152a/frameworks/projects/XML/src/main/flex/XML.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/XML/src/main/flex/XML.as 
b/frameworks/projects/XML/src/main/flex/XML.as
new file mode 100644
index 0000000..69d94b5
--- /dev/null
+++ b/frameworks/projects/XML/src/main/flex/XML.as
@@ -0,0 +1,2237 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You 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.
+//
+////////////////////////////////////////////////////////////////////////////////
+COMPILE::JS
+{
+package
+{
+       public class XML
+       {
+               /*
+                * Dealing with namespaces:
+                * If the name is qualified, it has a prefix. Otherwise, the 
prefix is null.
+                * Additionally, it has a namespaceURI. Otherwise the 
namespaceURI is null.
+                * the prefix together with the namespaceURI form a QName
+               */
+
+               static private var defaultNamespace:Namespace;
+
+               static public function setDefaultNamespace(ns:*)
+               {
+                       if(!ns)
+                               defaultNamespace = null;
+                       else
+                               ns = new Namespace(ns);
+               }
+
+               /**
+                * [static] Determines whether XML comments are ignored when 
XML objects parse the source XML data.
+                *  
+                */
+               static public var ignoreComments:Boolean = true;
+               
+               /**
+                * [static] Determines whether XML processing instructions are 
ignored when XML objects parse the source XML data.
+                *  
+                */
+               static public var ignoreProcessingInstructions:Boolean = true;
+               
+               /**
+                * [static] Determines whether white space characters at the 
beginning and end of text nodes are ignored during parsing.
+                *  
+                */
+               static public var ignoreWhitespace:Boolean = true;
+               
+               static private var _prettyIndent:int = 2;
+               /**
+                * [static] Determines the amount of indentation applied by the 
toString() and toXMLString() methods when the XML.prettyPrinting property is 
set to true.
+                * 
+                */
+               static public function set prettyIndent(value:int):void
+               {
+                       _prettyIndent = value;
+                       _indentStr = "";
+                       for(var i:int = 0; i < value; i++)
+                       {
+                               _indentStr = _indentStr + INDENT_CHAR;
+                       }
+               }
+
+               static public function get prettyIndent():int
+               {
+                       return _prettyIndent;
+               }
+
+               static private var _indentStr:String = "  ";
+               static private var INDENT_CHAR:String = " ";
+               
+               /**
+                * [static] Determines whether the toString() and toXMLString() 
methods normalize white space characters between some tags.
+                * 
+                */
+               static public var prettyPrinting:Boolean = true;
+               
+               static private function 
escapeAttributeValue(value:String):String
+               {
+                       var outArr:Array = [];
+                       var arr = value.split("");
+                       var len:int = arr.length;
+                       for(var i:int=0;i<len;i++)
+                       {
+                               switch(arr[i])
+                               {
+                                       case "<":
+                                               outArr[i] = "&lt;";
+                                               break;
+                                       case "&":
+                                               outArr[i] = "&amp;";
+                                               break;
+                                       case "\u000A":
+                                               outArr[i] = "&#xA;";
+                                               break;
+                                       case "\u000D":
+                                               outArr[i] = "&#xD;";
+                                               break;
+                                       case "\u0009":
+                                               outArr[i] = "&#x9;";
+                                               break;
+                                       default:
+                                               outArr[i] = arr[i];
+                                               break;
+                               }
+                       }
+                       return outArr.join("");
+               }
+
+               static private function escapeElementValue(value:String):String
+               {
+                       var outArr:Array = [];
+                       var arr = value.split("");
+                       for(var 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("");
+               }
+
+               static private function 
insertAttribute(att:Attr,parent:XML):XML()
+               {
+                       var xml:XML = new XML();
+                       xml.setParent(parent);
+                       xml.setNodeKind("attribute");
+                       xml.setName(att.name);
+                       xml.setValue(att.value);
+                       parent.addChild(xml);
+                       return xml;
+               }
+               static private function 
iterateElement(node:Element,xml:XML):void
+               {
+                       // add attributes
+                       for(i=0;i<node.attributes.length;i++)
+                       {
+                               insertAttribute(node.attributes[i],xml);
+                       }
+                       // loop through childNodes which will be one of:
+                       // text, cdata, processing instrution or comment and 
add them as children of the element
+                       for(i=0;i<node.childNodes.length;i++)
+                       {
+                               var 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
+               */
+               static private function fromNode(node:Element):XML
+               {
+                       var xml:XML;
+                       var i:int;
+                       var data:* = node.nodeValue;
+                       switch(node.nodeType)
+                       {
+                               case 1:
+                                       //ELEMENT_NODE
+                                       xml = new XML();
+                                       xml.setNodeKind("element");
+                                       iterateElement(node,xml);
+                                       break;
+                               //case 2:break;// ATTRIBUTE_NODE (handled 
separately)
+                               case 3:
+                                       //TEXT_NODE
+                                       xml = new XML();
+                                       xml.setNodeKind("text");
+                                       xml.setValue(data);
+                                       break;
+                               case 4:
+                                       //CDATA_SECTION_NODE
+                                       xml = new XML();
+                                       xml.setNodeKind("text");
+                                       data = "<![CDATA[" + data + "]]>";
+                                       xml.setValue(data);
+                                       break;
+                               //case 5:break;//ENTITY_REFERENCE_NODE
+                               //case 6:break;//ENTITY_NODE
+                               case 7:
+                                       //PROCESSING_INSTRUCTION_NODE
+                                       xml = new XML();
+                                       
xml.setNodeKind("processing-instruction");
+                                       xml.setName(node.nodeName);
+                                       xml.setValue(data);
+                                       break;
+                               case 8:
+                                       //COMMENT_NODE
+                                       xml = new XML();
+                                       xml.setNodeKind("comment");
+                                       xml.setValue(data);
+                                       break;
+                               //case 9:break;//DOCUMENT_NODE
+                               //case 10:break;//DOCUMENT_TYPE_NODE
+                               //case 11:break;//DOCUMENT_FRAGMENT_NODE
+                               //case 12:break;//NOTATION_NODE
+                               default:
+                                       throw new TypeError("Unknown XML node 
type!");
+                                       break;
+                       }
+                       return xml;
+               }
+
+               static private function 
namespaceInArray(ns:Namespace,arr:Array,considerPrefix:Boolean=true):Boolean
+               {
+                       if(!arr)
+                               return false;
+                       var i:int;
+                       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;
+               }
+
+               static private function trimXMLWhitespace(value:String):String
+               {
+                       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.
+                * @return 
+                * 
+                */
+               static public function defaultSettings():Object
+               {
+                       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.
+                * @param rest
+                * 
+                */
+               static public function setSettings(value:Object):void
+               {
+                       if(!value)
+                               return;
+                               
+                   ignoreComments = value.ignoreComments === undefined ? 
ignoreComments : value.ignoreComments;
+                   ignoreProcessingInstructions = 
value.ignoreProcessingInstructions === undefined ? ignoreProcessingInstructions 
: value.ignoreProcessingInstructions;
+                   ignoreWhitespace = value.ignoreWhitespace === undefined ? 
ignoreWhitespace : value.ignoreWhitespace;
+                   prettyIndent = value.prettyIndent === undefined ? 
prettyIndent : value.prettyIndent;
+                   prettyPrinting = value.prettyPrinting === undefined ? 
prettyPrinting : value.prettyPrinting;
+               }
+               
+               /**
+                * [static] Retrieves the following properties: ignoreComments, 
ignoreProcessingInstructions, ignoreWhitespace, prettyIndent, and 
prettyPrinting.
+                * 
+                * @return 
+                * 
+                */
+               static public function settings():Object
+               {
+                       return {
+                           ignoreComments : ignoreComments,
+                           ignoreProcessingInstructions : 
ignoreProcessingInstructions,
+                           ignoreWhitespace : ignoreWhitespace,
+                           prettyIndent : prettyIndent,
+                           prettyPrinting : prettyPrinting
+                       }
+               }
+
+
+               public function XML(xml:String = null)
+               {
+                       if(xml)
+                       {
+                               var parser:DOMParser = new DOMParser();
+                               // get error namespace. It's different in 
different browsers.
+                               var errorNS:Element = 
parser.parseFromString('<', 
'application/xml').getElementsByTagName("parsererror")[0].namespaceURI;
+
+                               var doc:Document = parser.parseFromString(xml, 
"application/xml");
+
+                               //check for errors
+                               if(doc.getElementsByTagNameNS(errorNS, 
'parsererror').length > 0)
+                               throw new Error('XML parse error');
+                       
+                               var node:Element = doc.childNodes[0];
+                               _version = doc.xmlVersion;
+                               _encoding = doc.xmlEncoding;
+                               iterateElement(node,this);
+                               normalize();
+                       }
+                       //need to deal with errors 
https://bugzilla.mozilla.org/show_bug.cgi?id=45566
+                       
+                       // get rid of nodes we do not want 
+
+                       //loop through the child nodes and build XML obejcts 
for each.
+                       Object.defineProperty(this,"0",
+                               {
+                                       get: function() { return this; },
+                                       set: function(newValue:*) {
+                                       },
+                                       enumerable: true,
+                                       configurable: true
+                               }
+                       );
+
+               }
+               
+               private var _children:Array;
+               private var _attributes:Array;
+               private var _processingInstructions:Array;
+               private var _parentXML:XML;
+               private var _name:*;
+               private var _value:String;
+               private var _version:String;
+               private var _encoding:String;
+               private var _appliedNamespace:Namespace;
+               private var _namespaces:Array = [];
+
+
+               /**
+                * @private
+                * 
+                * Similar to appendChild, but accepts all XML types (text, 
comment, processing-instruction, attribute, or element)
+                *
+                *      
+                */
+               public function addChild(child:XML):void
+               {
+                       if(!child)
+                               return;
+                       
+                       child.setParent(this);
+                       if(child.nodeKind() =="attribute")
+                       {
+                               if(!_attributes)
+                                       _attributes = [];
+
+                               _attributes.push(child);
+
+                       }
+                       else
+                               _children.push(child);
+                       normalize();
+               }
+
+
+               /**
+                * Adds a namespace to the set of in-scope namespaces for the 
XML object.
+                *
+                * @param ns
+                * @return 
+                *      
+                */
+               public function addNamespace(ns:Namespace):XML
+               {
+                       /*
+                               When the [[AddInScopeNamespace]] method of an 
XML object x is called with a namespace N, the following steps are taken:
+                               1. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction", “attribute”}, return
+                               2. If N.prefix != undefined
+                                 a. If N.prefix == "" and x.[[Name]].uri == 
"", return
+                                 b. Let match be null
+                                 c. For each ns in x.[[InScopeNamespaces]]
+                                   i. If N.prefix == ns.prefix, let match = ns
+                                 d. If match is not null and match.uri is not 
equal to N.uri
+                                   i. Remove match from x.[[InScopeNamespaces]]
+                                 e. Let x.[[InScopeNamespaces]] = 
x.[[InScopeNamespaces]] ∪ { N }
+                                 f. If x.[[Name]].[[Prefix]] == N.prefix
+                                   i. Let x.[[Name]].prefix = undefined
+                                 g. For each attr in x.[[Attributes]]
+                                   i. If attr.[[Name]].[[Prefix]] == N.prefix, 
let attr.[[Name]].prefix = undefined
+                               3. Return
+                       */
+                       if(_nodeKind == "text" || _nodeKind == "comment" || 
_nodeKind == "processing-instruction" || _nodeKind == "attribute")
+                               return this;
+                       if(ns.prefix === undefined)
+                               return this;
+                       if(ns.prefix == "" && name().uri == "")
+                               return this;
+                       var match:Namespace = null;
+                       var i:int;
+                       for(i=0;i<_namespaces.length;i++)
+                       {
+                               if(_namespaces[i].prefix == ns.prefix)
+                               {
+                                       match = _namespaces[i];
+                                       break;
+                               }
+                       }
+                       if(match)
+                               _namespaces[i] = ns;
+                       else
+                               _namespaces.push(ns);
+
+                       if(ns.prefix == name().prefix)
+                               name().prefix = undefined;
+
+                       for(i=0;i<_attributes.length;i++)
+                       {
+                               if(_attributes[i].name().prefix == ns.prefix)
+                                       _attributes[i].name().prefix = 
undefined;
+                       }
+                       return this;
+               }
+               
+               /**
+                * Appends the given child to the end of the XML object's 
properties.
+                *
+                * @param child
+                * @return 
+                * 
+                */
+               public function appendChild(child:XML):XML
+               {
+                       /*
+                               [[Insert]] (P, V)
+                               1. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction", "attribute"}, return
+                               2. Let i = ToUint32(P)
+                               3. If (ToString(i) is not equal to P), throw a 
TypeError exception
+                               4. If Type(V) is XML and (V is x or an ancestor 
of x) throw an Error exception
+                               5. Let n = 1
+                               6. If Type(V) is XMLList, let n = V.[[Length]]
+                               7. If n == 0, Return
+                               8. For j = x.[[Length]]-1 downto i, rename 
property ToString(j) of x to ToString(j + n)
+                               9. Let x.[[Length]] = x.[[Length]] + n
+                               10. If Type(V) is XMLList
+                                 a. For j = 0 to V.[[Length-1]]
+                                   i. V[j].[[Parent]] = x
+                                   ii. x[i + j] = V[j]
+                               11. Else
+                                 a. Call the [[Replace]] method of x with 
arguments i and V
+                               12. Return
+                       */
+                       child.setParent(this);
+                       
+                       _children.push(child);
+                       normalize();
+                       return child;
+               }
+               
+               
+               /**
+                * Returns the XML value of the attribute that has the name 
matching the attributeName parameter.
+                *
+                * @param attributeName
+                * @return 
+                * 
+                */
+               public function attribute(attributeName:*):XMLList
+               {
+                       var i:int;
+                       if(attributeName == "*")
+                               return attributes();
+
+                       attributeName = toAttributeName(attributeName);
+                       var list:XMLList = new XMLList();
+                       for(i=0;i<_attributes.length;i++)
+                       {
+                               if(_atributes[i].name().matches(attributeName))
+                                       list.appendChild(_atributes[i]);
+                       }
+                       list.targetObject = this;
+                       list.targetProperty = attributeName;
+                       return list;
+               }
+               
+               /**
+                * Returns a list of attribute values for the given XML object.
+                *
+                * @return 
+                * 
+                */
+               public function attributes():XMLList
+               {
+                       var list:XMLList = new XMLList();
+                       for(i=0;i<_attributes.length;i++)
+                               list.appendChild(_atributes[i]);
+
+                       list.targetObject = this;
+                       return list;
+               }
+               
+               /**
+                * Lists the children of an XML object.
+                *
+                * @param propertyName
+                * @return 
+                * 
+                */
+               public function child(propertyName:Object):XMLList
+               {
+                       /*
+                        * 
+                       When the [[Get]] method of an XML object x is called 
with property name P, the following steps are taken:
+                       1. If ToString(ToUint32(P)) == P
+                         a. Let list = ToXMLList(x)
+                         b. Return the result of calling the [[Get]] method of 
list with argument P
+                       2. Let n = ToXMLName(P)
+                       3. Let list be a new XMLList with list.[[TargetObject]] 
= x and list.[[TargetProperty]] = n
+                       4. If Type(n) is AttributeName
+                         a. For each a in x.[[Attributes]]
+                           i. If ((n.[[Name]].localName == "*") or 
(n.[[Name]].localName == a.[[Name]].localName)) and ((n.[[Name]].uri == null) 
or (n.[[Name]].uri == a.[[Name]].uri))
+                             1. Call the [[Append]] method of list with 
argument a
+                         b. Return list
+                       5. For (k = 0 to x.[[Length]]-1)
+                         a. If ((n.localName == "*") or ((x[k].[[Class]] == 
"element") and (x[k].[[Name]].localName == n.localName))) and ((n.uri == null) 
or ((x[k].[[Class]] == “element”) and (n.uri == x[k].[[Name]].uri)))
+                           i. Call the [[Append]] method of list with argument 
x[k]
+                       6. Return list
+                       */
+                       var i:int;
+                       var list:XMLList = new XMLList();
+                       if(parseInt(name,10).toString() == propertyName)
+                       {
+                               if(propertyName != "0")
+                                       return undefined;
+                               list.appendChild(this);
+                               list.targetObject = this;
+                               return list;
+                       }
+                       propertyName = toXMLName(propertyName);
+                       if(propertyName.isAttribute)
+                       {
+                               for(i=0;i<_attributes.length;i++)
+                               {
+                                       
if(propertyName.matches(_attributes[i].name()))
+                                               list.append(_attributes[i]);
+                               }
+                       }
+                       else
+                       {
+                               for(i=0;i<_children.length;i++)
+                               {
+                                       
if(propertyName.matches(_children[i].name()))
+                                               list.append(_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.
+                *
+                * @return 
+                * 
+                */
+               public function childIndex():int
+               {
+                       if(!parent)
+                               return -1;
+
+                       return parent.getIndexOf(this);
+               }
+               
+               /**
+                * Lists the children of the XML object in the sequence in 
which they appear.
+                *
+                * @return 
+                * 
+                */
+               public function children():XMLList
+               {
+                       var list:XMLList = new XMLList();
+                       for(i=0;i<_children.length;i++)
+                               list.append(_children[i]);
+
+                       list.targetObject = this;
+                       return list;
+               }
+               
+               /**
+                * Lists the properties of the XML object that contain XML 
comments.
+                *
+                * @return 
+                * 
+                */
+               public function comments():XMLList
+               {
+                       var list:XMLList = new XMLList();
+                       for(i=0;i<_children.length;i++)
+                       {
+                               if(_children[i].nodeKind() == "comment" && 
propertyName.matches(_children[i].name()))
+                                       list.append(_children[i]);
+                       }
+                       list.targetObject = this;
+                       return list;
+               }
+               
+               public function concat(list:*):XMLList
+               {
+                       if(list is XML)
+                       {
+                               var newList:XMLList = new XMLList();
+                               newList.appendChild(list);
+                               list = newList;
+                       }
+                       if(!(list is XMLList))
+                               throw new TypeError("invalid type");
+
+                       var retVal:XMLList = new XMLList();
+                       retVal.appendChild(this);
+                       var item:XML;
+                       for each(item in list)
+                               retVal.appendChild(item);
+                               
+                       return retVal;
+               }
+
+               /**
+                * Compares the XML object against the given value parameter.
+                *
+                * @param value
+                * @return 
+                * 
+                */
+               public function contains(value:XML):Boolean
+               {
+                       return this.equals(value);
+               }
+               
+               /**
+                * Returns a copy of the given XML object.
+                * 
+                * @return 
+                * 
+                */
+               public function copy():XML
+               {
+                       /*
+                               When the [[DeepCopy]] method of an XML object x 
is called, the following steps are taken:
+                               1. Let y be a new XML object with 
y.[[Prototype]] = x.[[Prototype]], y.[[Class]] = x.[[Class]], y.[[Value]] = 
x.[[Value]], y.[[Name]] = x.[[Name]], y.[[Length]] = x.[[Length]]
+                               2. For each ns in x.[[InScopeNamespaces]]
+                                 a. Let ns2 be a new Namespace created as if 
by calling the constructor new Namespace(ns)
+                                 b. Let y.[[InScopeNamespaces]] = 
y.[[InScopeNamespaces]] ∪ { ns2 }
+                               3. Let y.[[Parent]] = null
+                               4. For each a in x.[[Attributes]]
+                                 a. Let b be the result of calling the 
[[DeepCopy]] method of a
+                                 b. Let b.[[Parent]] = y
+                                 c. Let y.[[Attributes]] = y.[[Attributes]] 
∪ { b }
+                               5. For i = 0 to x.[[Length]]-1
+                                 a. Let c be the result of calling the 
[[DeepCopy]] method of x[i]
+                                 b. Let y[i] = c
+                                 c. Let c.[[Parent]] = y
+                               6. Return y
+                       */
+                       var i:int;
+                       var xml:XML = new XML();
+                       xml.setNodeKind(_nodeKind);
+                       xml.setName(name());
+                       xml.setValue(_value);
+                       for(i-0;i<_namespaces.length;i++)
+                       {
+                               xml.addNamespace(new Namespace(_namespaces[i]));
+                       }
+                       //parent should be null by default
+                       for(i=0;i<_attributes.length;i++)
+                               xml.addChild(_attributes[i].copy());
+
+                       for(i=0;i<_children.length;i++)
+                               xml.addChild(_children[i].copy());
+                       
+                       return xml;
+               }
+
+               private function deleteChildAt(idx:int):void
+               {
+
+               }
+               
+               /**
+                * Returns all descendants (children, grandchildren, 
great-grandchildren, and so on) of the XML object that have the given name 
parameter.
+                * 
+                * @param name
+                * @return 
+                * 
+                */
+               public function descendants(name:Object = "*"):XMLList
+               {
+                       /*
+                               When the [[Descendants]] method of an XML 
object x is called with property name P, the following steps are taken:
+                               1. Let n = ToXMLName(P)
+                               2. Let list be a new XMLList with 
list.[[TargetObject]] = null
+                               3. If Type(n) is AttributeName
+                                 a. For each a in x.[[Attributes]]
+                                   i. If ((n.[[Name]].localName == "*") or 
(n.[[Name]].localName == a.[[Name]].localName)) and ((n.[[Name]].uri == null) 
or (n.[[Name]].uri == a.[[Name]].uri ))
+                                     1. Call the [[Append]] method of list 
with argument a
+                               4. For (k = 0 to x.[[Length]]-1)
+                                 a. If ((n.localName == "*") or 
((x[k].[[Class]] == "element") and (x[k].[[Name]].localName == n.localName))) 
and ((n.uri == null) or ((x[k].[[Class]] == "element") and (n.uri == 
x[k].[[Name]].uri)))
+                                   i. Call the [[Append]] method of list with 
argument x[k]
+                                 b. Let dq be the resultsof calling the 
[[Descendants]] method of x[k] with argument P
+                                 c. If dq.[[Length]] > 0, call the [[Append]] 
method of list with argument dq
+                               5. Return list
+                       */
+                       var i:int;
+                       name = toXMLName(name);
+                       var list:XMLList = new XMLList();
+                       if(name.isAttribute)
+                       {
+                               for(i=0;i<_attributes.length;i++)
+                               {
+                                       if(name.matches(_attributes[i].name()))
+                                               
list.appendChild(_attributes[i]);
+                               }
+                               for(i=0;i<_children.length;i++)
+                               {
+                                       if(_children[i].nodeKind() == "element")
+                                       {
+                                               
if(name.matches(_children[i].name()))
+                                                       
list.appendChild(_children[i]);
+
+                                               list = 
list.concat(_children[i].descendants());
+                                       } 
+                               }
+                       }
+                       return list;
+               }
+               
+               /**
+                * Lists the elements of an XML object. (handles E4X dot 
notation)
+                * 
+                * @param name
+                * @return 
+                * 
+                */
+               public function elements(name:Object = "*"):XMLList
+               {
+                       name = toXMLName(name);
+                       var list:XMLList = new XMLList();
+                       for(i=0;i<_children.length;i++)
+                       {
+                               if(_children[i].nodeKind() == "element" && 
name.matches(_children[i].name()))
+                                       list.append(_children[i]);
+                       }
+
+                       list.targetObject = this;
+                       list.targetProperty = name;
+                       return list;
+
+                       return null;
+               }
+
+               public function equals(xml:*):Boolean
+               {
+                       /*
+                               When the [[Equals]] method of an XML object x 
is called with value V, the following steps are taken:
+                               1. If Type(V) is not XML, return false
+                               2. If x.[[Class]] is not equal to V.[[Class]], 
return false
+                               3. If x.[[Name]] is not null
+                                 a. If V.[[Name]] is null, return false
+                                 b. If x.[[Name]].localName is not equal to 
V.[[Name]].localName, return false
+                                 c. If x.[[Name]].uri is not equal to 
V.[[Name]].uri, return false
+                               4. Else if V.[[Name]] is not null, return false
+                               5. If x.[[Attributes]] does not contain the 
same number of items as V.[[Attributes]], return false
+                               6. If x.[[Length]] is not equal to 
V.[[Length]], return false
+                               7. If x.[[Value]] is not equal to y[[Value]], 
return false
+                               8. For each a in x.[[Attributes]]
+                                 a. If V.[[Attributes]] does not contain an 
attribute b, such that b.[[Name]].localName == a.[[Name]].localName, 
b.[[Name]].uri == a.[[Name]].uri and b.[[Value]] == a.[[Value]], return false
+                               9. For i = 0 to x.[[Length]]-1
+                                 a. Let r be the result of calling the 
[[Equals]] method of x[i] with argument V[i]
+                                 b. If r == false, return false
+                               10. Return true
+                       */
+                       var i:int;
+                       if(!(xml is XML))
+                               return false;
+
+                       if(xml.nodeKind() != _nodeKind)
+                               return false;
+
+                       if(!name().equals(xml.name()))
+                               return false;
+                       var selfAttrs:Array = getAttributeArray();
+                       var xmlAttrs:Array = xml.getAttributeArray();
+                       if(selfAttrs.length != xmlAttrs.length)
+                               return false;
+                       //length comparison should not be necessary because xml 
always has a length of 1
+                       if(getValue() != xml.getValue())
+                               return false;
+
+                       for(i=0;i<selfAttrs.length;i++)
+                       {
+                               if(!xml.hasAttribute(selfAttrs[i]))
+                                       return false;
+                       }
+                       var selfChldrn:Array = getChildrenArray();
+                       var xmlChildren:Array = 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;
+               }
+
+               public function 
hasAttribute(nameOrXML:*,value:String=null):Boolean
+               {
+                       if(!_attributes)
+                               return false;
+                       var name:QName;
+                       if(nameOrXML is XML)
+                       {
+                               name = nameOrXML.name();
+                               value = nameOrXML.getValue();
+                       }
+                       else
+                       {
+                               name = new QName(nameOrXML);
+                       }
+                       var i:int;
+                       for(i=0;i<_attributes.length;i++)
+                       {
+                               if(name.matches(_attributes[i].name()))
+                               {
+                                       if(!value)
+                                               return true;
+                                       return value == 
_attributes[i].getValue();
+                               }
+                       }
+                       return false;
+               }
+
+               private function getAncestorNamespaces(namespaces:Array):Array
+               {
+                       //don't modify original
+                       namespaces = namespaces.slice();
+                       var nsIdx:int;
+                       var pIdx:int;
+                       if(_parentXML)
+                       {
+                               var parentNS:Array = 
_parentXML.inScopeNamespaces();
+                               var len:int = parentNS.length;
+                               for(pIdx=0;pIdx<len;pIdx++)
+                               {
+                                       var curNS:Namespace = parentNS[pIdx];
+                                       var doInsert:Boolean = 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 = 
_parentXML.getAncestorNamespaces(namespaces);
+                       }
+                       return namespaces;
+               }
+
+               public function getAttributeArray():Array
+               {
+                       return _attributes ? _attributes.slice() : [];
+               }
+               public function getChildrenArray():Array
+               {
+                       return _children ? _children.slice() : [];
+               }
+
+               public function getIndexOf(elem:XML):int
+               {
+                       return _children.indexOf(elem);
+               }
+               
+               private function getURI(prefix:String):String
+               {
+                       var i:int;
+                       var namespaces:Array = 
getAncestorNamespaces(_namespaces);
+                       for(i=0;i<namespaces.length;i++)
+                       {
+                               if(namespaces[i].prefix == prefix)
+                                       return namespaces[i].uri;
+                       }
+                       return "";
+               }
+
+               public function getValue():String
+               {
+                       return _value;
+               }
+               /**
+                * Checks to see whether the XML object contains complex 
content.
+                * 
+                * @return 
+                * 
+                */
+               public function hasComplexContent():Boolean
+               {
+                       /*
+                               When the hasComplexContent method is called on 
an XML object x, the following steps are taken:
+                               1. If x.[[Class]] ∈ {"attribute", "comment", 
"processing-instruction", "text"}, return false
+                               2. For each property p in x
+                               a. If p.[[Class]] == "element", return true
+                               3. Return false
+                       */
+                       if(_nodeKind == "attribute" || _nodeKind == "comment" 
|| _nodeKind == "processing-instruction" || _nodeKind == "text")
+                               return false;
+                       var i:int;
+                       for(i=0i<_children.length;i++)
+                       {
+                               if(_children[i].nodeKind() == "element")
+                                       return true;
+                       }
+                       return false;
+               }
+
+               public function hasOwnProperty(p:*):Boolean
+               {
+                       /*
+                               When the [[HasProperty]] method of an XML 
object x is called with property name P, the following steps are taken:
+                               1. If ToString(ToUint32(P)) == P
+                                 a. Return (P == "0")
+                               2. Let n = ToXMLName(P)
+                               3. If Type(n) is AttributeName
+                                 a. For each a in x.[[Attributes]]
+                                   i. If ((n.[[Name]].localName == "*") or 
(n.[[Name]].localName == a.[[Name]].localName)) and ((n.[[Name]].uri == null) 
or (n.[[Name]].uri == a.[[Name]].uri))
+                                     1. Return true
+                                 b. Return false
+                               4. For (k = 0 to x.[[Length]]-1)
+                                 a. If ((n.localName == "*") or 
((x[k].[[Class]] == "element") and (x[k].[[Name]].localName == n.localName))) 
and ((n.uri == null) or (x[k].[[Class]] == "element") and (n.uri == 
x[k].[[Name]].uri)))
+                                   i. Return true
+                               5. Return false
+                       */
+                       if(parseInt(p,10).toString() == p)
+                               return p == "0";
+                       var name:QName = toXMLName(p);
+                       var i:int;
+                       for(i=0;i<_attributes.length;i++)
+                       {
+                               if(_attributes[i].name().matches(name))
+                                       return true;
+                       }
+                       for(i=0;i<_children.length;i++)
+                       {
+                               if(_children[i].nodeKind() != "element")
+                                       continue;
+                               if(_children[i].name().matches(name))
+                                       return true;
+                       }
+                       return false;
+               }
+                               
+               /**
+                * Checks to see whether the XML object contains simple content.
+                * 
+                * @return 
+                * 
+                */
+               public function hasSimpleContent():Boolean
+               {
+                       /*
+                               When the hasSimpleContent method is called on 
an XML object x, the following steps are taken:
+                               1. If x.[[Class]] ∈ {"comment", 
"processing-instruction"}, return false
+                               2. For each property p in x
+                               a. If p.[[Class]] == "element", return false
+                               3. Return true
+                       */
+                       if(_nodeKind == "comment" || _nodeKind == 
"processing-instruction")
+                               return false;
+                       var i:int;
+                       for(i=0i<_children.length;i++)
+                       {
+                               if(_children[i].nodeKind() == "element")
+                                       return false;
+                       }
+                       return true;
+               }
+               
+               /**
+                * Lists the namespaces for the XML object, based on the 
object's parent.
+                * 
+                * @return 
+                * 
+                */
+               public function inScopeNamespaces():Array
+               {
+                       return _namespaces.slice();
+               }
+               
+               private function insertChildAt(child:XML,idx:int):void{
+                       /*
+                               When the [[Insert]] method of an XML object x 
is called with property name P and value V, the following steps are taken:
+                               1. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction", "attribute"}, return
+                               2. Let i = ToUint32(P)
+                               3. If (ToString(i) is not equal to P), throw a 
TypeError exception
+                               4. If Type(V) is XML and (V is x or an ancestor 
of x) throw an Error exception
+                               5. Let n = 1
+                               6. If Type(V) is XMLList, let n = V.[[Length]]
+                               7. If n == 0, Return
+                               8. For j = x.[[Length]]-1 downto i, rename 
property ToString(j) of x to ToString(j + n)
+                               9. Let x.[[Length]] = x.[[Length]] + n
+                               10. If Type(V) is XMLList
+                                 a. For j = 0 to V.[[Length-1]]
+                                   i. V[j].[[Parent]] = x
+                                   ii. x[i + j] = V[j]
+                               11. Else
+                                 a. Call the [[Replace]] method of x with 
arguments i and V
+                               12. Return
+                       */
+                       if(_nodeKind == "text" || _nodeKind == "comment" || 
_nodeKind == "processing-instruction" || _nodeKind == "attribute")
+                               return;
+                       if(!child)
+                               return;
+                       var parent:XML = child.parent();
+                       if(parent)
+                               parent.removeChild(child);
+                       child.setParent(this);
+                       _children.splice(idx,0,child);
+               }
+               /**
+                * Inserts the given child2 parameter after the child1 
parameter in this XML object and returns the resulting object.
+                * 
+                * @param child1
+                * @param child2
+                * @return 
+                * 
+                */
+               public function insertChildAfter(child1:Object, 
child2:Object):XML
+               {
+                       /*
+                               When the insertChildAfter method is called on 
an XML object x with parameters child1 and child2, the following steps are 
taken:
+                               1. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction", "attribute"}, return
+                               2. If (child1 == null)
+                               a. Call the [[Insert]] method of x with 
arguments "0" and child2
+                               b. Return x
+                               3. Else if Type(child1) is XML
+                               a. For i = 0 to x.[[Length]]-1
+                               i. If x[i] is the same object as child1
+                               1. Call the [[Insert]] method of x with a
+                       */
+                       if(_nodeKind == "text" || _nodeKind == "comment" || 
_nodeKind == "processing-instruction" || _nodeKind == "attribute")
+                               return null;
+                       if(!child1)
+                       {
+                               insertChildAt(child2,0);
+                               return child2;
+                       }
+                       var idx:int = _children.indexOf(child1);
+                       if(idx >= 0)
+                       {
+                               insertChildAt(child2,idx+1);
+                       }
+                       return child2;
+               }
+               
+               /**
+                * Inserts the given child2 parameter before the child1 
parameter in this XML object and returns the resulting object.
+                * 
+                * @param child1
+                * @param child2
+                * @return 
+                * 
+                */
+               public function insertChildBefore(child1:Object, 
child2:Object):XML
+               {
+                       /*
+                               When the insertChildBefore method is called on 
an XML object x with parameters child1 and child2, the following steps are 
taken:
+                               1. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction", "attribute"}, return
+                               2. If (child1 == null)
+                               a. Call the [[Insert]] method of x with 
arguments ToString(x.[[Length]]) and child2
+                               b. Return x
+                               3. Else if Type(child1) is XML
+                               a. For i = 0 to x.[[Length]]-1
+                               i. If x[i] is the same object as child1
+                               1. Call the [[Insert]] method of x with 
arguments ToString(i) and child2
+                               2. Return x
+                               4. Return                       
+                       */
+                       if(_nodeKind == "text" || _nodeKind == "comment" || 
_nodeKind == "processing-instruction" || _nodeKind == "attribute")
+                               return null;
+                       if(!child1)
+                       {
+                               insertChildAt(child2,_children.length);
+                               return child2;
+                       }
+                       var idx:int = _children.indexOf(child1);
+                       if(idx >= 0)
+                       {
+                               insertChildAt(child2,idx);
+                       }
+                       return child2;
+               }
+               
+               /**
+                * For XML objects, this method always returns the integer 1.
+                * 
+                * @return 
+                * 
+                */
+               public function length():int
+               {
+                       return 1;
+               }
+               
+               /**
+                * Gives the local name portion of the qualified name of the 
XML object.
+                * 
+                * @return 
+                * 
+                */
+               public function localName():Object
+               {
+                       return name().localName;
+               }
+
+               private var _name:QName;
+               
+               /**
+                * Gives the qualified name for the XML object.
+                * 
+                * @return 
+                * 
+                */
+               public function name():Object
+               {
+                       if(!_name)
+                               _name = new QName();
+                       return _name;
+               }
+               
+               /**
+                * If no parameter is provided, gives the namespace associated 
with the qualified name of this XML object.
+                * 
+                * @param prefix
+                * @return 
+                * 
+                */
+               public function namespace(prefix:String = null):*
+               {
+                       /*
+                               When the namespace method is called on an XML 
object x with zero arguments or one argument prefix, the following steps are 
taken:
+                               1. Let y = x
+                               2. Let inScopeNS = { }
+                               3. While (y is not null)
+                                 a. For each ns in y.[[InScopeNamespaces]]
+                                   i. If there exists no n ∈ inScopeNS, such 
that n.prefix == ns.prefix
+                                     1. Let inScopeNS = inScopeNS ∪ { ns }
+                                 b. Let y = y.[[Parent]]
+                               4. If prefix was not specified
+                                 a. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction"}, return null
+                                 b. Return the result of calling the 
[[GetNamespace]] method of x.[[Name]] with argument inScopeNS
+                               5. Else
+                                 a. Let prefix = ToString(prefix)
+                                 b. Find a Namespace ns ∈ inScopeNS, such 
that ns.prefix = prefix. If no such ns exists, let ns = undefined.
+                                 c. Return ns
+                       */
+                       var i:int;
+                       if(prefix)
+                       {
+                               for(i=0;i<_namespaces.length;i++)
+                               {
+                                       if(_namespaces[i].prefix == prefix)
+                                               return _namespaces[i];
+                               }
+                               if(_parent)
+                                       return _parent.namespace(prefix);
+                               return undefined;
+                       }
+                       //no prefix. get the namespace of our object
+                       if(_nodeKind == "text" || _nodeKind ==  "comment" || 
_nodeKind ==  "processing-instruction")
+                               return null;
+                       return name().getNamespace(namespaceDeclarations());
+               }
+               
+               /**
+                * Lists namespace declarations associated with the XML object 
in the context of its parent.
+                * 
+                * @return 
+                * 
+                */
+               public function namespaceDeclarations():Array
+               {
+                       /*
+                               When the namespaceDeclarations method is called 
on an XML object x, the following steps are taken:
+                               1. Let a be a new Array created as if by 
calling the constructor, new Array()
+                               2. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction", "attribute"}, return a
+                               3. Let y = x.[[Parent]]
+                               4. Let ancestorNS = { }
+                               5. While (y is not null)
+                                 a. For each ns in y.[[InScopeNamespaces]]
+                                   i. If there exists no n ∈ ancestorNS, 
such that n.prefix == ns.prefix
+                                     1. Let ancestorNS = ancestorNS ∪ { ns }
+                                 b. Let y = y.[[Parent]]
+                               6. Let declaredNS = { }
+                               7. For each ns in x.[[InScopeNamespaces]]
+                                 a. If there exists no n ∈ ancestorNS, such 
that n.prefix == ns.prefix and n.uri == ns.uri
+                                   i. Let declaredNS = declaredNS ∪ { ns }
+                               8. Let i = 0
+                               9. For each ns in declaredNS
+                                 a. Call the [[Put]] method of a with 
arguments ToString(i) and ns
+                                 b. Let i = i + 1
+                               10. Return a
+                       */
+                       var retVal:Array = [];
+                       if(_nodeKind == "text" || _nodeKind == "comment" || 
_nodeKind == "processing-instruction" || _nodeKind ==  "attribute")
+                               return retVal;
+                       var declaredNS:Array = _namespaces.slice();
+                       var parent:XML = _parent;
+                       while(parent)
+                       {
+                               var parentNS:Array = parent.inScopeNamespaces();
+                               var idx:int;
+                               var pIdx:int;
+                               for(pIdx=0;i<parentNS.length;pIdx++)
+                               {
+                                       var uri:String = parentNS[pIdx].uri;
+                                       var prefix: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 var _nodeKind:String = "element";
+               /**
+                * Specifies the type of node: text, comment, 
processing-instruction, attribute, or element.
+                * @return 
+                * 
+                */
+               public function nodeKind():String
+               {
+                       return _nodeKind;
+               }
+               
+               /**
+                * For the XML object and all descendant XML objects, merges 
adjacent text nodes and eliminates empty text nodes.
+                * 
+                * @return 
+                * 
+                */
+               public function normalize():XML
+               {
+                       var len:int = _children.length-1;
+                       var lastChild:XML;
+                       for(var i:int=len;i>=0;i--)
+                       {
+                               var child:XML = _children[i];
+                               // can we have a null child?
+
+                               if(child.nodeKind() == "element")
+                               {
+                                       child.normalize();
+                               }
+                               else if(child.nodeKind() == "text")
+                               {
+                                       if(lastChild && lastChild.nodeKind() == 
"text")
+                                       {
+                                               child.setValue(child.text() + 
lastChild.text());
+                                               deleteChildAt(i+1);
+                                       }
+                                       if(!child.text())
+                                               deleteChildAt(i);
+                               }
+                               lastChild = child;
+                       }
+                       return this;
+               }
+               
+               /**
+                * Returns the parent of the XML object.
+                * 
+                * @return 
+                * 
+                */
+               public function parent():*
+               {
+                       return _parent;
+               }
+               
+               /**
+                * Inserts the provided child object into the XML element 
before any existing XML properties for that element.
+                * @param value
+                * @return 
+                * 
+                */
+               public function prependChild(child:XML):XML
+               {
+                       child.setParent(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.
+                * 
+                * @param name
+                * @return 
+                * 
+                */
+               public function processingInstructions(name:String = 
"*"):XMLList
+               {
+                       return null;
+               }
+               
+               /**
+                * Removes the given chid for this object and returns the 
removed child.
+                * 
+                * @param child
+                * @return 
+                * 
+                */
+               public function removeChild(child:XML):Boolean
+               {
+                       /*
+                               When the [[Delete]] method of an XML object x 
is called with property name P, the following steps are taken:
+                               1. If ToString(ToUint32(P)) == P, throw a 
TypeError exception
+                               NOTE this operation is reserved for future 
versions of E4X.
+                               2. Let n = ToXMLName(P)
+                               3. If Type(n) is AttributeName
+                                 a. For each a in x.[[Attributes]]
+                                   i. If ((n.[[Name]].localName == "*") or 
(n.[[Name]].localName == a.[[Name]].localName)) and ((n.[[Name]].uri == null) 
or (n.[[Name]].uri == a.[[Name]].uri))
+                                     1. Let a.[[Parent]] = null
+                                     2. Remove the attribute a from 
x.[[Attributes]]
+                                 b. Return true
+                               4. Let dp = 0
+                               5. For q = 0 to x.[[Length]]-1
+                                 a. If ((n.localName == "*") or 
(x[q].[[Class]] == "element" and x[q].[[Name]].localName == n.localName)) and 
((n.uri == null) or (x[q].[[Class]] == “element” and n.uri == 
x[q].[[Name]].uri ))
+                                   i. Let x[q].[[Parent]] = null
+                                   ii. Remove the property with the name 
ToString(q) from x
+                                   iii. Let dp = dp + 1
+                                 b. Else
+                                   i. If dp > 0, rename property ToString(q) 
of x to ToString(q – dp)
+                               6. Let x.[[Length]] = x.[[Length]] - dp
+                               7. Return true.
+                       */
+                       var removed:XML;
+                       if(!child)
+                               return false;
+                       if(!_attributes)
+                               return false;
+
+                       if(!(child is XML))
+                               return removeChildByName(child);
+                       
+                       if(child.nodeKind() == "attribute")
+                       {
+                               for(i=0;i<_attributes.length;i++)
+                               {
+                                       if(child.equals(_attributes[i]))
+                                       {
+                                               removed = _attributes[i];
+                                               removed.setParent(null);
+                                               _attributes.splice(i,1);
+                                               return true;
+                                       }
+                               }
+                       }
+                       var idx:int = _children.indexOf(child);
+                       if(idx < 0)
+                               return false;
+                       removed = _children.splice(idx,1);
+                       child.setParent(null);
+                       return removed;
+               }
+               private function removeChildByName(name:*):Boolean
+               {
+                       var i:int;
+                       name = toXMLName(name);
+                       child = null;
+                       var removedItem:Boolean = false;
+                       if(name.isAttribute)
+                       {
+                               if(!_attributes)
+                                       return false;
+
+                               for(i=_attributes.length-1;i>=0;i--)
+                               {
+                                       if(_attributes[i].name().matches(name))
+                                       {
+                                               child = _attributes[i];
+                                               child.setParent(null);
+                                               _attributes.splice(i,1);
+                                               removedItem = true;
+                                       }
+                               }
+                               return removedItem;
+                       }
+                       //QUESTION am I handling non-elements correctly?
+                       if(!_children)
+                               return false;
+                       for(i=_children.length-1;i>=0;i--)
+                       {
+                               if(_children[i].name().matches(name))
+                               {
+                                       child = _children[i];
+                                       child.setParent(null);
+                                       _children.splice(i,1);
+                                       removedItem = true;
+                               }
+                       }
+                       return removedItem;
+               }
+               public function removeChildAt(index:int):void
+               {
+                       /*
+                               When the [[DeleteByIndex]] method of an XML 
object x is called with property name P, the following steps are taken:
+                               1. Let i = ToUint32(P)
+                               2. If ToString(i) == P
+                                 a. If i is less than x.[[Length]]
+                                   i. If x has a property with name P
+                                     1. Let x[P].[[Parent]] = null
+                                     2. Remove the property with the name P 
from x
+                                   ii. For q = i+1 to x.[[Length]]-1
+                                     1. Rename property ToString(q) of x to 
ToString(q – 1)
+                                   iii. Let x.[[Length]] = x.[[Length]] – 1
+                                 b. Return true
+                               3. Else throw a TypeError exception
+                       */
+                       //Do nothing for XML objects?
+                       throw new Error("Cannot call delete on XML");
+               }
+
+               /**
+                * Removes the given namespace for this object and all 
descendants.
+                * 
+                * @param ns
+                * @return 
+                * 
+                */
+               public function removeNamespace(ns:*):XML
+               {
+                       /*
+                               Overview
+                               The removeNamespace method removes the given 
namespace from the in scope namespaces of this object and all its descendents,
+                               then returns a copy of this XML object. The 
removeNamespaces method will not remove a namespace from an object where it is 
referenced
+                               by that object’s QName or the QNames of that 
object’s attributes.
+                               Semantics
+                               When the removeNamespace method is called on an 
XML object x with parameter namespace, the following steps are taken:
+                               1. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction", "attribute"}, return x
+                               2. Let ns be a Namespace object created as if 
by calling the function Namespace( namespace )
+                               3. Let thisNS be the result of calling 
[[GetNamespace]] on x.[[Name]] with argument x.[[InScopeNamespaces]]
+                               4. If (thisNS == ns), return x
+                               5. For each a in x.[[Attributes]]
+                                 a. Let aNS be the result of calling 
[[GetNamespace]] on a.[[Name]] with argument x.[[InScopeNamespaces]]
+                                 b. If (aNS == ns), return x
+                               6. If ns.prefix == undefined
+                                 a. If there exists a namespace n ∈ 
x.[[InScopeNamespaces]], such that n.uri == ns.uri, remove the namespace n from 
x.[[InScopeNamespaces]]
+                               7. Else
+                                 a. If there exists a namespace n ∈ 
x.[[InScopeNamespaces]], such that n.uri == ns.uri and n.prefix == ns.prefix, 
remove the namespace n from x.[[InScopeNamespaces]]
+                               8. For each property p of x
+                                 a. If p.[[Class]] = "element", call the 
removeNamespace method of p with argument ns
+                               9. Return x
+                       */
+                       var i:int;
+                       if(_nodeKind == "text" || _nodeKind == "comment" || 
_nodeKind == "processing-instruction" || _nodeKind == "attribute")
+                               return this;
+                       if(!(ns is Namespace))
+                               ns = new Namespace(ns);
+                       if(ns == name().getNamespace(_namespaces))
+                               return this;
+                       for(i=0;i<_attributes.length;i++)
+                       {
+                               if(ns == 
_attributes[i].name().getNamespace(_namespaces))
+                                       return this;
+                       }
+                       
+                       //
+                       for(i=_namespaces.length-1;i>=0;i--)
+                       {
+                               if(_namespaces[i].uri == ns.uri && 
_namespaces[i].prefix == ns.prefix)
+                                       _namespaces.splice(i,1);
+                               else if(ns.prefix == undefined && 
_namespaces[i].uri == ns.uri)
+                                       _namespaces.splice(i,1);
+                       }
+                       for(i=0;i<_children.length;i++)
+                       {
+                               if(_children[i].nodeKind() == "element")
+                                       _children[i].removeNamespace(ns);
+                       }
+                       return this;
+               }
+               
+               /**
+                * Replaces the properties specified by the propertyName 
parameter with the given value parameter.
+                * 
+                * @param propertyName
+                * @param value
+                * @return 
+                * 
+                */
+               public function replace(propertyName:Object, value:*):XML
+               {
+                       /*
+                               Semantics
+                               When the replace method is called on an XML 
object x with parameters propertyName and value, the following steps are taken:
+                               1. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction", "attribute"}, return x
+                               2. If Type(value) ∉ {XML, XMLList}, let c = 
ToString(value)
+                               3. Else let c be the result of calling the 
[[DeepCopy]] method of value
+                               4. If ToString(ToUint32(P)) == P
+                                 a. Call the [[Replace]] method of x with 
arguments P and c and return x
+                               5. Let n be a QName object created as if by 
calling the function QName(P)
+                               6. Let i = undefined
+                               7. For k = x.[[Length]]-1 downto 0
+                                 a. If ((n.localName == "*") or 
((x[k].[[Class]] == "element") and (x[k].[[Name]].localName==n.localName))) and 
((n.uri == null) or ((x[k].[[Class]] == "element") and (n.uri == 
x[k].[[Name]].uri )))
+                                   i. If (i is not undefined), call the 
[[DeleteByIndex]] method of x with argument ToString(i)
+                                   ii. Let i = k
+                               8. If i == undefined, return x
+                               9. Call the [[Replace]] method of x with 
arguments ToString(i) and c
+                               10. Return x                    
+                       */
+                       if(_nodeKind == "text" || _nodeKind == "comment" || 
_nodeKind == "processing-instruction" || _nodeKind ==  "attribute")
+                               return this;
+                       if(value === null || value === undefined)
+                               return this;
+                       if((value is XML) || (value is XMLList))
+                               value = value.copy();
+                       else
+                               value = value.toString();
+
+                       return null;
+               }
+
+               private function replaceChild(idx:int,v:*):void
+               {
+                       /*
+                               When the [[Replace]] method of an XML object x 
is called with property name P and value V, the following steps are taken:
+                               1. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction", "attribute"}, return
+                               2. Let i = ToUint32(P)
+                               3. If (ToString(i) is not equal to P), throw a 
TypeError exception
+                               4. If i is greater than or equal to 
x.[[Length]],
+                                 a. Let P = ToString(x.[[Length]])
+                                 b. Let x.[[Length]] = x.[[Length]] + 1
+                               5. If Type(V) is XML and V.[[Class]] ∈ 
{"element", "comment", "processing-instruction", "text"}
+                                 a. If V.[[Class]] is “element” and (V is 
x or an ancestor of x) throw an Error exception
+                                 b. Let V.[[Parent]] = x
+                                 c. If x has a property with name P
+                                 i. Let x[P].[[Parent]] = null
+                                 d. Let x[P] = V
+                               6. Else if Type(V) is XMLList
+                                 a. Call the [[DeleteByIndex]] method of x 
with argument P
+                                 b. Call the [[Insert]] method of x with 
arguments P and V
+                               7. Else
+                                 a. Let s = ToString(V)
+                                 b. Create a new XML object t with t.[[Class]] 
= "text", t.[[Parent]] = x and t.[[Value]] = s
+                                 c. If x has a property with name P
+                                   i. Let x[P].[[Parent]] = null
+                                 d. Let the value of property P of x be t
+                               8. Return
+                       */
+                       if(_nodeKind == "text" || _nodeKind == "comment" || 
_nodeKind == "processing-instruction" || _nodeKind ==  "attribute")
+                               return this;
+                       if(idx > _children.length)
+                               idx = _children.length;
+                       if(v is XML && v.nodeKind() != "attribute")
+                       {
+                               if(v.nodeKind() == "element" && (v==this || 
isAncestor(v)) )
+                                       throw new TypeError("cannot assign 
parent xml as child");
+                               v.setParent(this);
+                               if(_children[idx])
+                                       _children[idx].setParent(null);
+                               _children[idx] = v;
+                       }
+                       else if(v is XMLList)
+                       {
+                               //6.
+                               if(_children[idx])
+                                       _children[idx].setParent(null);
+
+                       }
+                       else
+                       {
+                               //7. attribute?
+                       }
+               }
+
+               private function isAncestor(xml:XML):Boolean
+               {
+                       var p:XML = parent();
+                       while(p)
+                       {
+                               if(p == xml)
+                                       return true;
+                               p = p.parent();
+                       }
+                       return false;
+               }
+
+               public function setAttribute(attr:*,value:String):void
+               {
+                       var i:int;
+                       if(!_attributes)
+                               _attributes = [];
+
+                       if(attr is XML)
+                       {
+                               if(attr.nodeKind() == "attribute")
+                               {
+                                       for(i=0;i<_attributes.length;i++)
+                                       {
+                                               if(_attributes[i].name.equals() 
)
+                                               addChild(_att)
+                                       }
+                               }
+
+                       }
+                       if(attr.indexOf("xmlns") == 0)
+                       {
+                               //it's a namespace declaration
+                               var ns:Namespace = new 
Namespace(value.toString());
+                               if(attr.indexOf("xmlns:") == 0)// it has a 
prefix
+                                       ns.prefix = attr.split(":")[1];
+                               this.addNamespace(ns);
+                       }
+                       else
+                       {
+                               //it's a regular attribute string
+
+                       }
+
+               }
+               /**
+                * 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.
+                * 
+                * @param value
+                * @return 
+                * 
+                */
+               public function setChild(elementName:*, elements:Object):void
+               {
+                       
+                       /*
+                        * 
+                       1. If ToString(ToUint32(P)) == P, throw a TypeError 
exception NOTE this operation is reserved for future versions of E4X.
+                       2. If x.[[Class]] ∈ {"text", "comment", 
"processing-instruction", "attribute"}, return
+                       3. If (Type(V) ∉ {XML, XMLList}) or (V.[[Class]] ∈ 
{"text", "attribute"})
+                         a. Let c = ToString(V)
+                       4. Else
+                         a. Let c be the result of calling the [[DeepCopy]] 
method of V
+                       5. Let n = ToXMLName(P)
+                       6. If Type(n) is AttributeName
+                         a. Call the function isXMLName (section 13.1.2.1) 
with argument n.[[Name]] and if the result is false, return
+                         b. If Type(c) is XMLList
+                           i. If c.[[Length]] == 0, let c be the empty string
+                           ii. Else
+                             1. Let s = ToString(c[0])
+                             2. For i = 1 to c.[[Length]]-1
+                               a. Let s be the result of concatenating s, the 
string " " (space) and ToString(c[i])
+                             3. Let c = s
+                         c. Else
+                           i. Let c = ToString(c)
+                         d. Let a = null
+                         e. For each j in x.[[Attributes]]
+                           i. If (n.[[Name]].localName == 
j.[[Name]].localName) and ((n.[[Name]].uri == null) or (n.[[Name]].uri == 
j.[[Name]].uri))
+                             1. If (a == null), a = j
+                             2. Else call the [[Delete]] method of x with 
argument j.[[Name]]
+                         f. If a == null
+                           i. If n.[[Name]].uri == null
+                             1. Let nons be a new Namespace created as if by 
calling the constructor new Namespace()
+                             2. Let name be a new QName created as if by 
calling the constructor new QName(nons, n.[[Name]])
+                           ii. Else
+                             1. Let name be a new QName created as if by 
calling the constructor new QName(n.[[Name]])
+                           iii. Create a new XML object a with a.[[Name]] = 
name, a.[[Class]] == "attribute" and a.[[Parent]] = x
+                           iv. Let x.[[Attributes]] = x.[[Attributes]] ∪ { a 
}
+                           v. Let ns be the result of calling the 
[[GetNamespace]] method of name with no arguments
+                           vi. Call the [[AddInScopeNamespace]] method of x 
with argument ns
+                         g. Let a.[[Value]] = c
+                         h. Return
+                       7. Let isValidName be the result of calling the 
function isXMLName (section 13.1.2.1) with argument n
+                       8. If isValidName is false and n.localName is not equal 
to the string "*", return
+                       9. Let i = undefined
+                       10. Let primitiveAssign = (Type(c) ∉ {XML, XMLList}) 
and (n.localName is not equal to the string "*")
+                       11. For (k = x.[[Length]]-1 downto 0)
+                         a. If ((n.localName == "*") or ((x[k].[[Class]] == 
"element") and (x[k].[[Name]].localName==n.localName))) and ((n.uri == null) or 
((x[k].[[Class]] == “element”) and (n.uri == x[k].[[Name]].uri )))
+                           i. If (i is not undefined), call the 
[[DeleteByIndex]] property of x with argument ToString(i)
+                           ii. Let i = k
+                       12. If i == undefined
+                         a. Let i = x.[[Length]]
+                         b. If (primitiveAssign == true)
+                           i. If (n.uri == null)
+                             1. Let name be a new QName created as if by 
calling the constructor new QName(GetDefaultNamespace(), n)
+                           ii. Else
+                             1. Let name be a new QName created as if by 
calling the constructor new QName(n)
+                           iii. Create a new XML object y with y.[[Name]] = 
name, y.[[Class]] = "element" and y.[[Parent]] = x
+                           iv. Let ns be the result of calling 
[[GetNamespace]] on name with no arguments
+                           v. Call the [[Replace]] method of x with arguments 
ToString(i) and y
+                           vi. Call [[AddInScopeNamespace]] on y with argument 
ns
+                       13. If (primitiveAssign == true)
+                         a. Delete all the properties of the XML object x[i]
+                         b. Let s = ToString(c)
+                         c. If s is not the empty string, call the [[Replace]] 
method of x[i] with arguments "0" and s
+                       14. Else
+                         a. Call the [[Replace]] method of x with arguments 
ToString(i) and c
+                       15. Return
+                       */
+                       var i:int;
+                       var len:int;
+                       var chld:XML;
+                       
+                       if(elements is XML)
+                       {
+                               var list:XMLList = new XMLList();
+                               list[0] = elements;
+                               elements = list;
+                       }
+                       if(elements is XMLList)
+                       {
+                               var chldrn:XMLList = this.child(elementName);
+                               var childIdx:int = children().length() -1;
+                               if(chldrn.length())
+                                       childIdx = chldrn[0].childIndex();
+                               
+                               len = chldrn.length() -1;
+                               for (i= len; i >= 0;  i--)
+                               {
+                                       removeChild(chldrn[i]);
+                                       // remove the nodes
+                                       // remove the children
+                                       // adjust the childIndexes
+                               }
+                               var curChild = _children[childIdx];
+                               // Now add them in.
+                               len = elements.length();
+                               for(i=0;i<len;i++)
+                               {
+                                       child = elements[i];
+                                       if(!curChild)
+                                       {
+                                               curChild = appendChild(chld);
+                                       }
+                                       else {
+                                               curChild = 
insertChildAfter(curChild, chld);
+                                       }
+                               }
+                       }
+                       //what to do if it's not XML or XMLList? Throw an 
error? Ignore?
+                       
+               }
+
+               /**
+                * Replaces the child properties of the XML object with the 
specified set of XML properties, provided in the value parameter.
+                * 
+                * @param value
+                * @return 
+                * 
+                */
+               public function setChildren(value:Object):XML
+               {
+                       if(value is XML)
+                       {
+                               var list:XMLList = new XMLList();
+                               list[0] = value;
+                               value = list;
+                       }
+                       if(value is XMLList)
+                       {
+                               // remove all existing elements
+                               var chldrn:XMLList = this.child(elementName);
+                               var childIdx:int = children().length() -1;
+                               if(chldrn.length())
+                                       childIdx = chldrn[0].childIndex();
+                               
+                               len = chldrn.length() -1;
+                               for (i= len; i >= 0;  i--)
+                               {
+                                       removeChild(chldrn[i]);
+                                       // remove the nodes
+                                       // remove the children
+                                       // adjust the childIndexes
+                               }
+                               var curChild = _children[childIdx];
+                               // Now add them in.
+                               len = value.length();
+                               for(i=0;i<len;i++)
+                               {
+                                       child = value[i];
+                                       if(!curChild)
+                                       {
+                                               curChild = appendChild(chld);
+                                       }
+                                       else {
+                                               curChild = 
insertChildAfter(curChild, chld);
+                                       }
+                               }
+                       }
+
+                       return this;
+               }
+               
+               /**
+                * Changes the local name of the XML object to the given name 
parameter.
+                * 
+                * @param name
+                * 
+                */
+               public function setLocalName(name:String):void
+               {
+                       if(!_name)
+                               _name = new QName();
+
+                       _name.localName = name;
+               }
+               
+               /**
+                * Sets the name of the XML object to the given qualified name 
or attribute name.
+                * 
+                * @param name
+                * 
+                */
+               public function setName(name:*):void
+               {
+                       if(name is QName)
+                               _name = name;
+                       else
+                               _name = new QName(name);
+               }
+               
+               /**
+                * Sets the namespace associated with the XML object.
+                * 
+                * @param ns
+                * 
+                */
+               public function setNamespace(ns:Object):void
+               {
+                       if(_nodeKind == "text" || _nodeKind == "comment" || 
_nodeKind == "processing-instruction")
+                               return;
+                       var ns2:Namespace = new Namespace(ns);
+                       _name = new QName(ns2,name());
+
+                       if(_nodeKind == "attribute")
+                       {
+                               _name.isAttribute = true;
+                               if(_parent == null)
+                                       return;
+                               _parent.addNamespace(ns2);
+                       }
+                       if(_nodeKind == "element")
+                               addNamespace(ns2);
+               }
+
+               /**
+                * @private
+                * 
+                */
+               public function setNodeKind(value:String):void
+               {
+                       _nodeKind = value;
+               }
+               
+               public function setParent(parent:XML):void
+               {
+                       if(_parentXML)
+                               _parentXML.removeChild(this);
+                       _parentXML = parent;
+               }
+
+               public function setValue(value:String):void
+               {
+                       _value = value;
+               }
+               
+               /**
+                * Returns an XMLList object of all XML properties of the XML 
object that represent XML text nodes.
+                * 
+                * @return 
+                * 
+                */
+               public function text():XMLList
+               {
+                       var list:XMLList = new XMLList();
+                       var i:int;
+                       for(i=0;i<_children.length;i++)
+                       {
+                               if(_children[i].nodeKind() == "text")
+                                       list.list.appendChild(_atributes[i]);
+                       }
+                       list.targetObject = this;
+                       return list;
+               }
+               
+               /**
+                * Provides an overridable method for customizing the JSON 
encoding of values in an XML object.
+                * 
+                * @param k
+                * @return 
+                * 
+                */
+               public function toJSON(k:String):*
+               {
+                       return this.name();
+               }
+               
+               /**
+                * Returns a string representation of the XML object.
+                * 
+                * @return 
+                * 
+                */
+               public function toString():String
+               {
+                       // text, comment, processing-instruction, attribute, or 
element
+                       if(_nodeKind == "text" || _nodeKind == "attribute")
+                               return _value;
+                       if(_nodeKind == "comment")
+                               return "";
+                       if(_nodeKind == "processing-instruction")
+                               return "";
+                       return toXMLString();
+               }
+
+               private function toAttributeName(name:*):QName
+               {
+                       if(!name is QName)
+                       {
+                               name = name.toString();
+                               if(name.indexOf("@") > -1)
+                                       name = 
name.substring(name.indexOf("@"));
+                       }
+                       name = toXMLName(name);
+                       name.isAttribute = true;
+
+               }
+               private function toXMLName(name:*):QName
+               {
+                       if(name.toString().indexOf("@") > -1)
+                               return toAttributeName(name);
+
+                       /*
+                               Given a string s, the ToXMLName conversion 
function returns a QName object or AttributeName. If the first character of s 
is "@", ToXMLName creates an AttributeName using the ToAttributeName operator. 
Otherwise, it creates a QName object using the QName constructor.
+                               Semantics
+                               Given a String value s, ToXMLName operator 
converts it to a QName object or AttributeName using the following steps:
+                               1. If ToString(ToUint32(s)) == ToString(s), 
throw a TypeError exception
+                               2. If the first character of s is "@"
+                               a. Let name = s.substring(1, s.length)
+                               b. Return ToAttributeName(name)
+                               3. Else
+                               a. Return a QName object created as if by 
calling the constructor new QName(s)
+                       */
+                       if(parseInt(name,10).toString() == name)
+                               throw new TypeError("invalid element name");
+
+                       if(!name is QName)
+                       {
+                               name = name.toString();
+                               if(name.indexOf(":") >= 0)
+                               {
+                                       // Get the QName for prefix
+                                       var qname:QName() = new QName();
+                                       qname.prefix = 
name.substring(0,name.indexOf(":"));
+                                       qname.localName = 
name.substring(name.lastIndexOf(":")+1);
+                                       //get the qname uri
+                                       qname.uri = getURI(qname.prefix);
+                                       name = qname;
+                               }
+                               else
+                               {
+                                       qname = new QName(name());
+                                       if(!qname.uri && defaultNamespace)
+                                       {
+                                               qname = new 
QName(defaultNamespace);
+                                       }
+                                       qname.localName = name;
+                                       name = qname;
+                               }
+                       }
+                       else
+                       {
+                               name  = new QName(name);
+                       }
+                       return name;
+               }
+               
+               /**
+                * Returns a string representation of the XML object.
+                * 
+                * @return 
+                * 
+                */
+               public function 
toXMLString(indentLevel:int=0,ancestors:Array=[]):String
+               {
+                       /*
+                               Given an XML object x and an optional argument 
AncestorNamespaces and an optional argument IndentLevel, ToXMLString converts 
it to an XML encoded string s by taking the following steps:
+                               1. Let s be the empty string
+                               2. If IndentLevel was not provided, Let 
IndentLevel = 0
+                               3. If (XML.prettyPrinting == true)
+                                 a. For i = 0 to IndentLevel-1, let s be the 
result of concatenating s and the space <SP> character
+                               4. If x.[[Class]] == "text",
+                                 a. If (XML.prettyPrinting == true)
+                                   i. Let v be the result of removing all the 
leading and trailing XMLWhitespace characters from x.[[Value]]
+                                   ii. Return the result of concatenating s 
and EscapeElementValue(v)
+                                 b. Else
+                                   i. Return EscapeElementValue(x.[[Value]])
+                               5. If x.[[Class]] == "attribute", return the 
result of concatenating s and EscapeAttributeValue(x.[[Value]])
+                               6. If x.[[Class]] == "comment", return the 
result of concatenating s, the string "<!--", x.[[Value]] and the string "-->"
+                               7. If x.[[Class]] == "processing-instruction", 
return the result of concatenating s, the string "<?", x.[[Name]].localName, 
the space <SP> character, x.[[Value]] and the string "?>"
+                               8. If AncestorNamespaces was not provided, let 
AncestorNamespaces = { }
+                               9. Let namespaceDeclarations = { }
+                               10. For each ns in x.[[InScopeNamespaces]]
+                                 a. If there is no ans ∈ AncestorNamespaces, 
such that ans.uri == ns.uri and ans.prefix == ns.prefix
+                                   i. Let ns1 be a copy of ns
+                                   ii. Let namespaceDeclarations = 
namespaceDeclarations ∪ { ns1 } NOTE implementations may also exclude unused 
namespace declarations from namespaceDeclarations
+                               11. For each name in the set of names 
consisting of x.[[Name]] and the name of each attribute in x.[[Attributes]]
+                                 a. Let namespace be a copy of the result of 
calling [[GetNamespace]] on name with argument (AncestorNamespaces ∪ 
namespaceDeclarations)
+                                 b. If (namespace.prefix == undefined),
+                                   i. Let namespace.prefix be an arbitrary 
implementation defined namespace prefix, such that there is no ns2 ∈ 
(AncestorNamespaces ∪ namespaceDeclarations) with namespace.prefix == 
ns2.prefix
+                                   ii. Note: implementations should prefer the 
empty string as the implementation defined prefix if it is not already used in 
the set (AncestorNamespaces ∪ namespaceDeclarations)
+                                   iii. Let namespaceDeclarations = 
namespaceDeclarations ∪ { namespace }
+                               12. Let s be the result of concatenating s and 
the string "<"
+                               13. If namespace.prefix is not the empty string,
+                                 a. Let s be the result of concatenating s, 
namespace.prefix and the string ":"
+                               14. Let s be the result of concatenating s and 
x.[[Name]].localName
+                               15. Let attrAndNamespaces = x.[[Attributes]] 
∪ namespaceDeclarations
+                               16. For each an in attrAndNamespaces
+                                 a. Let s be the result of concatenating s and 
the space <SP> character
+                                 b. If Type(an) is XML and an.[[Class]] == 
"attribute"
+                                   i. Let ans be a copy of the result of 
calling [[GetNamespace]] on a.[[Name]] with argument AncestorNamespaces
+                                   ii. If (ans.prefix == undefined),
+                                     1. Let ans.prefix be an arbitrary 
implementation defined namespace prefix, such that there is no ns2 ∈ 
(AncestorNamespaces ∪ namespaceDeclarations) with ans.prefix == ns2.prefix
+                                     2. If there is no ns2 ∈ 
(AncestorNamespaces ∪ namespaceDeclarations), such that ns2.uri == ans.uri 
and ns2.prefix == ans.prefix
+                                       a. Let namespaceDeclarations = 
namespaceDeclarations ∪ { ans }
+                                   iii. If ans.prefix is not the empty string
+                                     1. Let s be the result of concatenating 
s, namespace.prefix and the string ":"
+                                   iv. Let s be the result of concatenating s 
and a.[[Name]].localName
+                                 c. Else
+                                   i. Let s be the result of concatenating s 
and the string "xmlns"
+                                   ii. If (an.prefix == undefined),
+                                     1. Let an.prefix be an arbitrary 
implementation defined namespace prefix, such that there is no ns2 ∈ 
(AncestorNamespaces ∪ namespaceDeclarations) with an.prefix == ns2.prefix
+                                   iii. If an.prefix is not the empty string
+                                     1. Let s be the result of concatenating 
s, the string ":" and an.prefix
+                                 d. Let s be the result of concatenating s, 
the string "=" and a double-quote character (i.e. Unicode codepoint \u0022)
+                                 e. If an.[[Class]] == "attribute"
+                                   i. Let s be the result of concatenating s 
and EscapeAttributeValue(an.[[Value]])
+                                 f. Else
+                                   i. Let s be the result of concatenating s 
and EscapeAttributeValue(an.uri)
+                                 g. Let s be the result of concatenating s and 
a double-quote character (i.e. Unicode codepoint \u0022)
+                               17. If x.[[Length]] == 0
+                                 a. Let s be the result of concatenating s and 
"/>"
+                                 b. Return s
+                               18. Let s be the result of concatenating s and 
the string ">"
+                               19. Let indentChildren = ((x.[[Length]] > 1) or 
(x.[[Length]] == 1 and x[0].[[Class]] is not equal to "text"))
+                               20. If (XML.prettyPrinting == true and 
indentChildren == true)
+                                 a. Let nextIndentLevel = IndentLevel + 
XML.PrettyIndent.
+                               21. Else
+                                 a. Let nextIndentLevel = 0
+                               22. For i = 0 to x.[[Length]]-1
+                                 a. If (XML.prettyPrinting == true and 
indentChildren == true)
+                                   i. Let s be the result of concatenating s 
and a LineTerminator
+                                 b. Let child = ToXMLString (x[i], 
(AncestorNamespaces ∪ namespaceDeclarations), nextIndentLevel)
+                                 c. Let s be the result of concatenating s and 
child
+                               23. If (XML.prettyPrinting == true and 
indentChildren == true),
+                                 a. Let s be the result of concatenating s and 
a LineTerminator
+                                 b. For i = 0 to IndentLevel, let s be the 
result of concatenating s and a space <SP> character
+                               24. Let s be the result of concatenating s and 
the string "</"
+                               25. If namespace.prefix is not the empty string
+                                 a. Let s be the result of concatenating s, 
namespace.prefix and the string ":"
+                               26. Let s be the result of concatenating s, 
x.[[Name]].localName and the string ">"
+                               27. Return s
+                               NOTE Implementations may also preserve 
insignificant whitespace (e.g., inside and between element tags) and attribute 
quoting conventions in ToXMLString().                     
+                       */
+                       var i:int;
+                       var ns:Namespace;
+                       var strArr:Array = [];
+
+                       var indentArr:Array = [];
+                       for(i=0;i<indentLevel;i++)
+                               indentArr.push(_indentStr);
+
+                       var indent:String = indentArr.join("");
+                       if(this.nodeKind() == "text")
+                       {
+                               if(prettyPrinting)
+                               {
+                                       var v:String = 
trimXMLWhitespace(_value);
+                                       return indent + escapeElementValue(v);
+                               }
+                               return escapeElementValue(_value);
+                       }
+                       if(this.nodeKind() == "attribute")
+                               return indent + escapeAttributeValue(_value);
+
+                       if(this.nodeKind() == "comment")
+                               return indent + "<!--" +  _value + "-->";
+
+                       if(this.nodeKind() == "processing-instruction")
+                               return indent + "<?" + name().localName + " " + 
_value + "?>";
+
+                       // We excluded the other types, so it's a normal element
+                       //TODO I'm here...
+                       // step 8.
+                       //ancestors
+                       var declarations:Array = [];
+                       for(i=0;i<_namespaces.length;i++)
+                       {
+                               if(!namespaceInArray(_namespaces[i],ancestors))
+                                       declarations.push(new 
Namespace(_namespaces[i]));
+                       }
+                       //11
+                       for(i=0;i<_attributes.length)
+                       {
+                               ns = new 
Namespace(_attributes[i].name().getNamespace(ancestors.concat(declarations)));
+                               if(ns.prefix === null)
+                               {
+                                       ns.prefix = "";
+                                       declarations.push(ns);
+                               }
+                       }
+                       ns = new 
Namespace(name().getNamespace(ancestors.concat(declarations)));
+                       if(ns.prefix === null)
+                       {
+                               ns.prefix = "";
+                               declarations.push(ns);
+                       }
+                       strArray.push("<");
+                       if(ns.prefix)
+                               strArr.push(ns.prefix+":");
+                       strArray.push(name().localName);
+
+                       //attributes and namespace declarations... (15-16)
+                       for(i=0;i<declarations.length;i++)
+                       {
+                               strArray.push(" xmlns");
+                               if(declarations[i].prefix)
+                               {
+                                       strArray.push(":");
+                                       strArray.push(declarations[i].prefix);
+                               }
+                               strArray.push('="');
+                               
strArray.push(escapeAttributeValue(declarations[i].uri));
+                               strArray.push('"');
+
+                       }
+                       for(i=0;i<_attributes.length;i++)
+                       {
+                               strArray.push(" ");
+                               // the following seems to be the spec, but it 
does not make sense to me.
+                               //var ans:Namespace = 
_attributes[i].name().getNamespace(ancestors);
+                               var aName:QName = _attributes[i].name();
+                               var ans:Namespace = 
aName.getNamespace(ancestors.concat(declarations));
+                               if(ans.prefix)
+                               {
+                                       strArray.push(ans.prefix);
+                                       strArray.push(":");
+                               }
+                               strArray.push(aName.localName);
+                               strArray.push('="');
+                               
strArray.push(escapeAttributeValue(_attributes[i].getValue()));
+                               strArray.push('"');
+                       }
+                       // now write elements or close the tag if none exist
+                       if(_children.length == 0)
+                       {
+                               strArray.push("/>");
+                               return strArray.join("");
+                       }
+                       strArray.push(">");
+                       var indentChildren:Boolean = _children.length > 1 || 
(_children.length == 1 && _children[0].nodeKind() != "text");
+                       var nextIndentLevel:int;
+                       if(XML.prettyPrinting && indentChildren)
+                               nextIndentLevel = indentLevel + prettyIndent;
+                       else
+                               nextIndentLevel = 0;
+                       for(i=0;i<_children.length;i++)
+                       {
+                               //
+                               if(XML.prettyPrinting && indentChildren)
+                                       strArray.push("\n");
+                               
strArray.push(_children[i].toXMLString(nextIndentLevel,ancestors.concat(declarations)));
+                       }
+                       if(XML.prettyPrinting && indentChildren)
+                       {
+                               strArray.push("\n");
+                               strArray.push(new Array(indentLevel + 1).join(' 
'));
+                       }
+                       strArray.push("</");
+                       if(ns.prefix)
+                       {
+                               strArray.push(ns.prefix);
+                               strArray.push(":");
+                       }
+                       strArray.push(ns.localName);
+                       strArray.push(">");
+
+                       return strArray.join("");
+               }
+               
+               /**
+                * Returns the XML object.
+                * 
+                * @return 
+                * 
+                */
+               public function valueOf():XML
+               {
+                       return this;
+               }
+               
+       }
+}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/a487152a/frameworks/projects/XML/src/main/flex/XMLClasses.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/XML/src/main/flex/XMLClasses.as 
b/frameworks/projects/XML/src/main/flex/XMLClasses.as
new file mode 100644
index 0000000..6a91d82
--- /dev/null
+++ b/frameworks/projects/XML/src/main/flex/XMLClasses.as
@@ -0,0 +1,35 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You 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.
+//
+////////////////////////////////////////////////////////////////////////////////
+package {
+
+/**
+ *  @private
+ *  This class is used to link additional classes into rpc.swc
+ *  beyond those that are found by dependency analysis starting
+ *  from the classes specified in manifest.xml.
+ */
+internal class XMLClasses
+{
+       COMPILE::JS
+       {
+               import XML; XML;
+               import XMLList; XMLList;
+               import QName; QName;
+       }
+}
\ No newline at end of file

Reply via email to