You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by gr...@apache.org on 2020/04/02 09:51:01 UTC

[royale-asjs] 03/03: Updates to XML classes to support improved e4x conformance.

This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 2d0f49560eb3953ff1549d683c9aae71c57af9ac
Author: greg-dove <gr...@gmail.com>
AuthorDate: Thu Apr 2 22:42:32 2020 +1300

    Updates to XML classes to support improved e4x conformance.
---
 frameworks/projects/XML/src/main/royale/XML.as     | 183 ++++++++-------
 .../projects/XML/src/main/royale/XMLClasses.as     |   1 +
 frameworks/projects/XML/src/main/royale/XMLList.as | 247 +++++++++++++++++++--
 .../flexUnitTests/xml/XMLListTesterGeneralTest.as  |  29 ++-
 .../royale/flexUnitTests/xml/XMLNamespaceTest.as   | 150 ++++++-------
 .../flexUnitTests/xml/XMLTesterGeneralTest.as      |  68 ++++--
 .../src/main/royale/flexUnitTests/XMLTester.as     |  12 +-
 .../flexUnitTests/xml/XMLListTesterGeneralTest.as  |  27 ++-
 .../royale/flexUnitTests/xml/XMLNamespaceTest.as   | 133 ++++++-----
 .../flexUnitTests/xml/XMLTesterGeneralTest.as      |  40 +++-
 10 files changed, 605 insertions(+), 285 deletions(-)

diff --git a/frameworks/projects/XML/src/main/royale/XML.as b/frameworks/projects/XML/src/main/royale/XML.as
index ccd283d..f876507 100644
--- a/frameworks/projects/XML/src/main/royale/XML.as
+++ b/frameworks/projects/XML/src/main/royale/XML.as
@@ -26,6 +26,7 @@ package
 	{
 		import org.apache.royale.debugging.assert;
 		import org.apache.royale.debugging.assertType;
+		import org.apache.royale.language.toAttributeName;
 		
 		/**
 		 * Memory optimization.
@@ -809,6 +810,8 @@ package
 		 * @param ns
 		 * @return
 		 *
+		 *
+		 * @royaleignorecoercion QName
 		 */
 		public function addNamespace(ns:Namespace):XML
 		{
@@ -868,7 +871,7 @@ package
 				var att:XML = _attributes[i];
 				if(att.name().prefix == ns.prefix)  {
 					
-					att._name = getQName(att._name.localName,null,att._name.uri,true);
+					att._name = getQName(QName(att._name).localName,null,QName(att._name).uri,true);
 				}
 			}
 			return this;
@@ -2035,7 +2038,7 @@ package
 		}
 		
 		/**
-		 * Removes the given chid for this object and returns the removed child.
+		 * Removes the given child for this object and returns the removed child.
 		 *
 		 * @param child
 		 * @return
@@ -2153,7 +2156,7 @@ package
 			normalize(); // <-- check this is correct
 			return removedItem;
 		}
-		public function removeChildAt(index:int):void
+		public function removeChildAt(index:int):Boolean
 		{
 			/*
 				When the [[DeleteByIndex]] method of an XML object x is called with property name P, the following steps are taken:
@@ -2170,7 +2173,14 @@ package
 				3. Else throw a TypeError exception
 			*/
 			//Do nothing for XML objects?
-			throw new Error("Cannot call delete on XML");
+			if (index < childrenLength()) {
+				var removed:XML = _children[index];
+				removed.setParent(null);
+				_children.splice(index,1);
+				return true;
+			}
+
+			throw new TypeError("Cannot call delete on XML at index "+index);
 		}
 		
 		/**
@@ -2250,8 +2260,9 @@ package
 		 */
 		public function replace(propertyName:Object, value:*):*
 		{
+			//@todo this is not finished - needs work, review and testing. Reference to [[Replace]] below should call 'replaceChildAt'
 			/*
-				Semantics
+				Semantics (x refers to 'this')
 				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)
@@ -2292,6 +2303,7 @@ package
 		public function replaceChildAt(idx:int,v:*):void
 		{
 			/*
+				**this is the [[Replace]] method in the spec**
 				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)
@@ -2354,7 +2366,12 @@ package
 			}
 			else
 			{
-				//7. attribute?
+				//7. this is a text node
+				chld = new XML();
+				chld.setValue(v + '');//7.a, 7.b
+				chld.setParent(this);
+				if (_children[idx] != null) (_children[idx] as XML).setParent(null);
+				_children[idx] = chld;
 			}
 		}
 		
@@ -2400,7 +2417,7 @@ package
 				return value;
 				
 			}
-			if(attr.indexOf("xmlns") == 0)
+			if(typeof attr == 'string' && attr.indexOf("xmlns") == 0)
 			{
 				//it's a namespace declaration
 				var ns:Namespace;
@@ -2437,12 +2454,14 @@ package
 		 * @param value
 		 * @return
 		 *
+		 * @royaleignorecoercion QName
+		 * @royaleignorecoercion XML
 		 */
 		public function setChild(elementName:*, elements:Object):Object
 		{
 			
 			/*
-			 *
+			 *  [[Put]]
 			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"})
@@ -2506,84 +2525,83 @@ package
 			15. Return
 			*/
 			var i:int;
-			var len:int;
+		/*	var len:int;
 			var chld:XML;
 			var retVal:Object = elements;
 			var chldrn:XMLList;
-			var childIdx:int;
-			
-			// I'm not sure that this a strict interpretation of the spec but I think this does the "right thing".
-			var childType:String = typeof elements;
-			if(childType != "object")
-			{
-				var stringable:XML = xmlFromStringable(elements);
-				chldrn = this.child(elementName);
-				childIdx = children().length() -1;
-				if(chldrn.length())
-					childIdx = chldrn[0].childIndex()-1;
-				else
-				{
-					chld = new XML("<" + elementName + "/>");
-					chld.appendChild(stringable);
-					prependChild(chld);
-					return chld;
-				}
-				len = chldrn.length() -1;
-				for (i= len; i > 0;  i--)
+			var childIdx:int;*/
+			if (uint(elementName).toString() == elementName) throw new TypeError('not permitted');
+			var ref:String = getNodeRef();
+			if(ref == TEXT || ref == COMMENT || ref == PROCESSING_INSTRUCTION || ref == ATTRIBUTE)
+				return this;
+			var n:QName = toXMLName(elementName); //5.
+
+			if (n.isAttribute) {
+				//@todo
+				return setAttribute(n, elements+'');
+			}
+
+			//7.0
+			//8.0
+
+
+
+		   //	elements = elements + ''; //13.b
+			i = -1;// undefined;
+			var wild:Boolean = n.localName == '*';
+			var primitiveAssign:Boolean = !wild && !(elements is XML || elements is XMLList);//primitiveAssign step 10.
+			var k:int = childrenLength() - 1; //11
+
+			while (k > -1) { //11
+				if (
+						( wild  || ((_children[k] as XML).getNodeRef() == ELEMENT &&  (_children[k] as XML).localName() == n.localName) )
+						&& (n.uri == null || ((_children[k] as XML).getNodeRef() == ELEMENT &&  QName((_children[k] as XML)._name).uri == n.uri)))
 				{
-					removeChild(chldrn[i]);
+					if (i !== -1) {
+						removeChildAt(i); //11.a.i
+					}
+					i = k; //11.a.ii
 				}
-				chld = chldrn[i];
-				chld.setChildren(stringable);
-				return chld;
-			}
-			
-			if(elements is XML)
-			{
-				var list:XMLList = new XMLList();
-				list[0] = elements;
-				elements = list;
+				k--;
 			}
-			if(elements is XMLList)
-			{
-				chldrn = this.child(elementName);
-				childIdx = children().length() -1;
-				if(chldrn.length())
-					childIdx = chldrn[0].childIndex()-1;
-				
-				len = chldrn.length() -1;
-				for (i= len; i >= 0;  i--)
-				{
-					removeChild(chldrn[i]);
-					// remove the nodes
-					// remove the children
-					// adjust the childIndexes
+			if (i == -1) { //12.
+				i = childrenLength(); //12.a
+				if (primitiveAssign) { //12.b
+					//skipping 12.b.i and 12.b.ii for now...@todo review
+					/*if (n.uri == null) {
+
+                    } else {
+
+                    }*/
+					_internal = true;
+					var y:XML = new XML();
+					_internal = false;
+					y._name = getQName(n.localName,n.prefix,n.uri,false);
+					y.setParent(this); //end of 12.n.iii
+					var ns:Namespace = new Namespace('', n);
+					replaceChildAt(i,y);
+					y.setNamespace(ns);//@todo check this for 12.b.iv and 12.b.vi
 				}
-				if(chldrn.length()){
-					var curChild:XML = getChildren()[childIdx];
+			}
+
+			if (primitiveAssign) { //13 @todo review guess at conditional
+				//13.a. Delete all the properties of the XML object x[i]
+				y = _children[i];
+				k = y.childrenLength() - 1;
+				while(k>-1) {
+					y.removeChildAt(k); //13.a
+					k--;
 				}
-				// Now add them in.
-				len = elements.length();
-				for(i=0;i<len;i++)
-				{
-					chld = elements[i];
-					if(!curChild)
-					{
-						curChild = chld
-						if(childIdx < 0)
-							prependChild(chld);
-						else
-							appendChild(chld);
-					}
-					else {
-						insertChildAfter(curChild, chld);
-						curChild = chld;
-					}
+				elements = elements + ''; //13.b
+				if (elements) {
+					y.replaceChildAt(0, elements); //13.c
 				}
+			} else {
+				//elements = (elements as XML).copy(); //@todo check... might need attention here
+				replaceChildAt(i, elements); //14.a
 			}
-			//what to do if it's not XML or XMLList? Throw an error? Ignore?
-			
-			return retVal;
+
+			return elements;
 		}
 		
 		/**
@@ -2685,8 +2703,12 @@ package
 				nameRef = name;
 			else
 				nameRef = new QName(name);
-			
-			_name = getQName(nameRef.localName,nameRef.prefix,nameRef.uri,ref == ATTRIBUTE);
+			var asAtttribute:Boolean = nameRef.isAttribute;
+			_name = getQName(nameRef.localName,nameRef.prefix,nameRef.uri,asAtttribute);
+			if (asAtttribute) {
+				//optimization, the name alone is sufficient to get the nodeKind() externally (see : getNodeRef())
+				delete this._nodeKind;
+			}
 		}
 		
 		/**
@@ -2833,7 +2855,7 @@ package
 		 *
 		 * @royaleignorecoercion QName
 		 */
-		private function toAttributeName(name:*):QName
+		/*private function toAttributeName(name:*):QName
 		{
 			const typeName:String = typeof name;
 			if (name == null || typeName == 'number'|| typeName == 'boolean') {
@@ -2857,7 +2879,8 @@ package
 				qname.setIsAttribute(true);
 			}
 			return qname;
-		}
+		}*/
+		
 		private function toXMLName(name:*):QName
 		{
 			/*
diff --git a/frameworks/projects/XML/src/main/royale/XMLClasses.as b/frameworks/projects/XML/src/main/royale/XMLClasses.as
index 46650eb..533b88e 100644
--- a/frameworks/projects/XML/src/main/royale/XMLClasses.as
+++ b/frameworks/projects/XML/src/main/royale/XMLClasses.as
@@ -34,6 +34,7 @@ internal class XMLClasses
 		import Namespace; Namespace;
 		import org.apache.royale.language.toXML; toXML;
 		import org.apache.royale.language.toXMLList; toXMLList;
+		import org.apache.royale.language.toAttributeName; toAttributeName;
 	}
 }
 }
diff --git a/frameworks/projects/XML/src/main/royale/XMLList.as b/frameworks/projects/XML/src/main/royale/XMLList.as
index 589c8c1..b2f9206 100644
--- a/frameworks/projects/XML/src/main/royale/XMLList.as
+++ b/frameworks/projects/XML/src/main/royale/XMLList.as
@@ -22,6 +22,7 @@ package
 	public class XMLList
 	{
 		import org.apache.royale.debugging.throwError;
+		import org.apache.royale.language.toAttributeName;
 		
 		/**
 		 * regex to match the xml declaration
@@ -108,6 +109,26 @@ package
                 }
             }
 		}
+
+		/**
+		 * [[ResolveValue]] from the e4x spec
+		 *  @royaleignorecoercion QName
+		 *  @royaleignorecoercion XMLList
+		 */
+		private function resolveValue():*{
+			if (_xmlArray.length > 0) return this;
+			if ((_targetObject == null || _targetProperty == null)
+					|| (_targetProperty is QName && (QName(_targetProperty).isAttribute || QName(_targetProperty).localName == '*'))) return null; //2,a
+			var base:* = (!_targetObject || _targetObject is XML) ? _targetObject : (_targetObject as XMLList).resolveValue();
+			if (base==null) return null;
+			var target:XMLList = base.child(_targetProperty);
+			if (target.length() == 0) {
+				if (base is XMLList && (base.length() > 1)) return null;
+				base.setChild(_targetProperty, '');
+				target = base.child(_targetProperty);
+			}
+			return target;
+		}
         
 		private var _xmlArray:Array = [];
 		/*
@@ -208,6 +229,54 @@ package
 				}
 			);
 		}
+
+
+		/*
+		[[Append]] from the e4x spec
+		When the [[Append]] method of an XMLList object x is called with value V, the following steps are taken:
+		1. Let i = x.[[Length]]
+		2. Let n = 1
+		3. If Type(V) is XMLList,
+		a. Let x.[[TargetObject]] = V.[[TargetObject]]
+		b. Let x.[[TargetProperty]] = V.[[TargetProperty]]
+		c. Let n = V.[[Length]]
+		d. If n == 0, Return
+		e. For j = 0 to V.[[Length]]-1, let x[i + j] = V[j]
+		f.
+		4. Let x.[[Length]] = x.[[Length]] + n
+		5. Return
+		 */
+		/**
+		 *
+		 * @royaleignorecoercion XMLList
+		 * @royaleignorecoercion XML
+		 */
+		private function Append(content:Object):void{
+			var i:uint = _xmlArray.length;
+			var n:uint = 1;
+			if (content is XMLList) {
+				var l:XMLList = content as XMLList;
+				_targetObject = l._targetObject;//3.a
+				_targetProperty = l._targetProperty;//3.b
+				n = l.length();//3.c
+				if (n == 0) return;//3.d
+				for (var j:uint =0; j < n; j++){
+					//[[Put]]
+					_xmlArray[i+j] = l._xmlArray[j]; //3.e
+					addIndex(i+j);
+					//setChild( i+j, l._xmlArray[j]);
+				}
+
+			} else {
+				if (content is XML) {
+					//[[Put]]
+					//setChild( i, content as XML); //3.e
+					_xmlArray[i] = content; //3.e
+					addIndex(i);
+				}
+			}
+		}
+
 		
 		public function append(child:XML):void
 		{
@@ -883,34 +952,50 @@ package
 		{
 			return _targetProperty;
 		}
-		private function xmlFromProperty():XML
+		private function xmlFromProperty(r:XML):XML
 		{
-			var xmlStr:String = "<";
-			if(_targetProperty is QName)
-			{
-				if(_targetProperty.prefix)
-					xmlStr += _targetProperty.prefix + "::";
-
-				xmlStr += _targetProperty.localName + "/>";
+			if (_targetProperty == null || _targetProperty == '*' ||  (_targetProperty is QName && QName(_targetProperty).localName == '*')) {
+				return new XML(); //text node
 			}
-			else
-			{
-				xmlStr += _targetProperty + "/>";
+			var ret:XML;
+			var str:String = _targetProperty as String;
+			ret = new XML();
+			ret.setParent(r);
+			if (str && str.charAt(0)=='@' ||  (_targetProperty is QName && QName(_targetProperty).isAttribute)) {
+				if (r.child(_targetProperty).length()) return null; //2.c.iv,2
+				ret.setName(_targetProperty);
+				// not needed, derived from the QName ret.setNodeKind('attribute');
+			} else {
+				var xmlStr:String = "<";
+				if(_targetProperty is QName)
+				{
+					if(_targetProperty.prefix)
+						xmlStr += _targetProperty.prefix + "::";
+
+					xmlStr += _targetProperty.localName + "/>";
+				}
+				else
+				{
+					xmlStr += _targetProperty + "/>";
+				}
+				ret = new XML(xmlStr);
 			}
-			return new XML(xmlStr);
+			
+			return ret;
 		}
 		public function setAttribute(attr:*,value:String):String
 		{
-			if(isEmpty() && targetObject)//walk up the tree and create nodes.
-				_xmlArray[0] = targetObject.setChild(_targetProperty,xmlFromProperty());
+			/*if(isEmpty() && targetObject)//walk up the tree and create nodes.
+				_xmlArray[0] = targetObject.setChild(_targetProperty,xmlFromProperty(targetObject));
 
 			var len:int = _xmlArray.length;
 			for (var i:int=0;i<len;i++)
-				_xmlArray[i].setAttribute(attr,value);
+				_xmlArray[i].setAttribute(attr,value);*/
+			setChild(toAttributeName(attr), value);
 			
 			return value;
-
 		}
+
 		public function hasAncestor(obj:*):Boolean
 		{
 			if(isSingle())
@@ -960,14 +1045,134 @@ package
 			if(isSingle())
 				return _xmlArray[0].replace(propertyName,value);
 		}
+
+		/**
+		 *
+		 * @royaleignorecoercion XMLList
+		 * [[Put]] from the e4X spec
+		 */
 		public function setChild(elementName:*, elements:Object):Object
 		{
-			if(isEmpty() && targetObject)//walk up the tree and create nodes.
-				_xmlArray[0] = targetObject.setChild(_targetProperty,xmlFromProperty());
+			var r:Object;
+			var idx:uint =uint(elementName);
+			if (idx + '' == elementName + '') { //[[PUT]] 2.0
+				if (_targetObject) { //2.a
+					if (_targetObject is XMLList)
+						r= (targetObject as XMLList).resolveValue(); //2.a.i
+					else r = _targetObject;
+					if (r == null) return null; //2.a.ii
+				} else {
+					r = null; //2.b
+				}
 
-			if(isSingle())
-				_xmlArray[0].setChild(elementName,elements);
-			
+				if (idx >= _xmlArray.length) { //2.c
+					var xmlR:XML = r as XML;
+					if (!r && r is XMLList) { //2.c.i
+						if (!(r as XMLList).isSingle()) return null; //2.c.i.1
+						xmlR = r[0]; //2.c.i.2
+					}
+					if (xmlR && xmlR.nodeKind() != 'element') return null; //2.c.ii
+					var y:XML = xmlFromProperty(xmlR);
+
+					idx = _xmlArray.length;
+					if (y.nodeKind() != 'attribute') {//2.c.vii
+						if (xmlR)  { //2.c.viii.1
+							if (idx > 0) { //2.c.viii.1.a
+								var j:uint = 0;
+								while (j < xmlR.getChildrenArray().length-1 && xmlR.getChildrenArray()[j] !==  _xmlArray[idx-1]) {
+									j++;
+								}
+							} else {
+								j = xmlR.getChildrenArray().length -1; //2.c.viii.1.b
+							}
+							xmlR.insertChildAfter(xmlR.getChildrenArray()[j], y); //2.c.viii.1.c
+						}
+						if (elements is XML) y.setName((elements as XML).name());//2.c.viii.2
+						else if (elements is XMLList) y.setName(new QName((elements as XMLList)._targetProperty)); //2.c.viii.3
+					}
+					//append(y);
+					Append(y);
+				}
+				if ( !(elements is XML || elements is XMLList)
+						|| (elements is XML && ((elements as XML).nodeKind() == 'text' || (elements as XML).nodeKind() == 'attribute')))  { //2.d
+					elements = elements + '';
+				}
+				if ((_xmlArray[idx] as XML).nodeKind() == 'attribute') {
+					var z:QName = (_xmlArray[idx] as XML).name();
+					(_xmlArray[idx] as XML).parent().setAttribute(z, elements);
+					var attr:XMLList = (_xmlArray[idx] as XML).parent().attribute(z);
+					_xmlArray[idx] = attr[0];
+					addIndex(idx);
+				} else if (elements is XMLList) {
+					var c:XMLList = new XMLList(elements); // 2.f.i (shallow copy)
+					var parent:XML = (_xmlArray[idx] as XML).parent();
+					if (parent) {
+						//1. Let q be the property of parent, such that parent[q] is the same object as x[i]  @todo verify what this actually means
+						var q:int = parent.getChildrenArray().indexOf(_xmlArray[idx]);
+						//2. Call the [[Replace]] method of parent with arguments q and c
+						parent.replaceChildAt(q, c);
+						for (j =0; j<c._xmlArray.length -1; j++) {
+							c.setChild(j, parent.getChildrenArray()[q+j])
+						}
+
+					}
+					if (c.length() == 0) {
+						_xmlArray.splice(idx, 1);
+						for (j = idx; j< length() -1; j++) {//variation of 2.f.iv.1
+							addIndex(j);
+						}
+					} else {
+						var l:uint = _xmlArray.length;
+						var cl:uint = c.length()-1;
+						for (j = l-1; j> idx; j--) {
+							_xmlArray[j+cl] = _xmlArray[j];
+							addIndex(j+cl);
+						}
+						for (j = 0; j< cl; j++) {
+							_xmlArray[idx+j] = c[j];
+							addIndex(idx+j);
+
+						}
+					}
+				} else if (elements is XML
+						|| (_xmlArray[idx] as XML).nodeKind() == 'text'
+						|| (_xmlArray[idx] as XML).nodeKind() == 'comment'
+						|| (_xmlArray[idx] as XML).nodeKind() == 'processing-instruction') {
+					parent = (_xmlArray[idx] as XML).parent();
+					if (parent) {
+						//1. Let q be the property of parent, such that parent[q] is the same object as x[i]  @todo verify what this actually means
+						q = parent.getChildrenArray().indexOf(_xmlArray[idx]);
+						//2. Call the [[Replace]] method of parent with arguments q and c
+						parent.replaceChildAt(q, elements);
+						elements = parent.getChildrenArray()[q];
+					}
+					if (typeof elements == 'string') {
+						var t:XML = new XML();
+						t.setParent(this as XML); //this is not XML... but we can cheat
+						t.setValue(elements+'');
+						_xmlArray[idx] = t;
+
+					} else {
+						_xmlArray[idx] = elements;
+					}
+					addIndex(idx);
+				} else {
+					(_xmlArray[idx] as XML).setChild('*', elements);
+				}
+			} else {
+				//3
+				if (_xmlArray.length <= 1) { //3.a
+				   if (isEmpty()) {
+					   r = resolveValue();
+					   if (r == null || r.length() != 1) return null;
+					   Append(r)
+				   }
+				   (_xmlArray[0] as XML).setChild(elementName, elements);
+				} else {
+					//match AVM, this is not covered in spec which says nothing, avm does this:
+					throw new TypeError('Error #1089: Assignment to lists with more than one item is not supported.')
+				}
+			}
 			return elements;
 		}
 
diff --git a/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as b/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as
index f1f4ccb..c9b9e6e 100644
--- a/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as
+++ b/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as
@@ -189,7 +189,32 @@ package flexUnitTests.xml
             //use length here to account for variation in attribute/namespace sequence outputs
             assertTrue( xmllist.toXMLString().length == 1431, 'XMLList length was unexpected');
         }
-        
-        
+
+        [Test]
+        public function testWithDecl():void{
+
+            var list:XMLList = new XMLList('<?xml version="1.0" encoding="utf-8"?><success>false</success><retryable>false</retryable><localStatus>SESSION_NO_SUCH_CUSTOMER</localStatus>');
+            assertEquals(list.length(), 3, 'unexpected parsing result for list content');
+
+        }
+
+        [Test]
+        public function testAssignmentRange():void{
+
+            var list:XMLList = new XMLList('<?xml version="1.0" encoding="utf-8"?><success>false</success><retryable>false</retryable><localStatus>SESSION_NO_SUCH_CUSTOMER</localStatus>');
+            assertEquals(list.length(), 3, 'unexpected parsing result for list content');
+            //out of range index assignment
+            list[10] = <message>You cannot login, please check with tech support</message>;
+
+            assertEquals(list.length(), 4, 'unexpected length result for list content');
+            assertEquals(list[3].toXMLString(),'<message>You cannot login, please check with tech support</message>', 'unexpected list content' );
+            var hadError:Boolean;
+            try{
+                list.@attr = 'testAtt'
+            } catch (e:Error) {
+                hadError = true;
+            }
+            assertTrue(hadError, 'expected an error');
+        }
     }
 }
diff --git a/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLNamespaceTest.as b/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLNamespaceTest.as
index c8a2f00..f4dbc8a 100644
--- a/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLNamespaceTest.as
+++ b/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLNamespaceTest.as
@@ -38,13 +38,25 @@ package flexUnitTests.xml
         
         public static var isJS:Boolean = COMPILE::JS;
     
-        private var settings:Object;
+        private static var settings:Object;
         
-        private var source:String;
+        private static var source:String;
         
         [Before]
         public function setUp():void
         {
+
+        }
+        
+        [After]
+        public function tearDown():void
+        {
+
+        }
+        
+        [BeforeClass]
+        public static function setUpBeforeClass():void
+        {
             settings = XML.settings();
             source = '<xml><?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?>\n' +
                     '<?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?>\n' +
@@ -73,24 +85,13 @@ package flexUnitTests.xml
                     '</rss></xml>';
         }
         
-        [After]
-        public function tearDown():void
-        {
-            source=null;
-            XML.setSettings(settings);
-        }
-        
-        [BeforeClass]
-        public static function setUpBeforeClass():void
-        {
-        }
-        
         [AfterClass]
         public static function tearDownAfterClass():void
         {
+            source=null;
+            XML.setSettings(settings);
         }
     
-    
         public function getPlayerVersion():Number{
             COMPILE::SWF{
                 import flash.system.Capabilities;
@@ -179,13 +180,10 @@ package flexUnitTests.xml
             var atomLinks:XMLList = xml.rss.channel.atom::link;
             assertEquals(atomLinks.length(),2, 'unexpected results from namespace based child query');
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
-          //  RoyaleUnitTestRunner.consoleOut(atomLinks.toString());
-            assertEquals(atomLinks.toString().length, 459, 'unexpected list content length');
             
-            /*RoyaleUnitTestRunner.consoleOut('atomLinks');
-            RoyaleUnitTestRunner.consoleOut(atomLinks.toString());
-            RoyaleUnitTestRunner.consoleOut(atomLinks.toString().length+'');*/
+            assertEquals(atomLinks.toString().length, 459, 'unexpected list content length');
             
+
         }
     
     
@@ -196,13 +194,10 @@ package flexUnitTests.xml
             var atomLinks:XMLList = xml..atom::link;
             assertEquals(atomLinks.length(),2, 'unexpected results from namespace based child query');
             //account for browser DOMParser variation to order of 'attributes' - use length comparison
-           // RoyaleUnitTestRunner.consoleOut(atomLinks.toString());
+
             assertEquals(atomLinks.toString().length, 459, 'unexpected list content length');
       
-            /*RoyaleUnitTestRunner.consoleOut('descendants atomLinks');
-            RoyaleUnitTestRunner.consoleOut(atomLinks.toString());
-            RoyaleUnitTestRunner.consoleOut(atomLinks.toString().length+'');*/
-            
+
         }
     
         [Test]
@@ -225,10 +220,7 @@ package flexUnitTests.xml
             assertEquals(inscopes.length, 2, 'unexpected namespace count');
             //account for browser DOMParser variation to order of 'attributes' - use length comparison
             assertEquals(inscopes.toString().length, 'http://www.w3.org/2005/Atom,nothing'.length, 'unexpected namespace content');
-           /* RoyaleUnitTestRunner.consoleOut(inscopes.length+":"+inscopes.toString());
-            for each(var ns:Namespace in inscopes) {
-                RoyaleUnitTestRunner.consoleOut('prefix:\''+ns.prefix+'\', '+ns.uri);
-            }*/
+
             
             var links:XMLList = feed.atom::link;
             var link1:XML = links[0];
@@ -238,10 +230,7 @@ package flexUnitTests.xml
             assertEquals(inscopes.length, 3, 'unexpected namespace count');
             //account for browser DOMParser variation to order of 'attributes' - use length comparison
             assertEquals(inscopes.toString().length, 'blah,http://www.w3.org/2005/Atom,nothing'.length, 'unexpected namespace content');
-           /* RoyaleUnitTestRunner.consoleOut(inscopes.length+":"+inscopes.toString());
-            for each(var ns:Namespace in inscopes) {
-                RoyaleUnitTestRunner.consoleOut('prefix:\''+ns.prefix+'\', '+ns.uri);
-            }*/
+
         }
     
         [Test]
@@ -322,20 +311,14 @@ package flexUnitTests.xml
             
 
             list = testInstance.test2();
-           /* RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('2 end -----------------'+list.length());
-            RoyaleUnitTestRunner.consoleOut(String(list.toXMLString().length));*/
-    
+
             assertEquals(list.length(), 5, 'unexpected list length');
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
             assertEquals(list.toXMLString().length, 572, 'unexpected list content');
             
             
             list = testInstance.test3();
-           /* RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('3 end -----------------'+list.length());
-            RoyaleUnitTestRunner.consoleOut(String(list.toXMLString().length));*/
-    
+
             assertEquals(list.length(), 4, 'unexpected list length');
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
             assertEquals(list.toXMLString().length, 466, 'unexpected list content');
@@ -343,10 +326,7 @@ package flexUnitTests.xml
     
           
             list = testInstance.test4();
-            /*RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('4 end -----------------'+list.length());
-            RoyaleUnitTestRunner.consoleOut(String(list.toXMLString().length));*/
-    
+
             assertEquals(list.length(), 4, 'unexpected list length');
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
             assertEquals(list.toXMLString().length, 466, 'unexpected list content');
@@ -357,33 +337,22 @@ package flexUnitTests.xml
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
             assertEquals(list.toXMLString().length, 618, 'unexpected list content');
             
-           /* RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('11 end -----------------'+list.length());
-            RoyaleUnitTestRunner.consoleOut(String(list.toXMLString().length));*/
-            
-            
+
             list = testInstance.test12();
             assertEquals(list.length(), 6, 'unexpected list length');
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
             assertEquals(list.toXMLString().length, 729, 'unexpected list content');
-           /* RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('12 end -----------------'+list.length());
-            RoyaleUnitTestRunner.consoleOut(String(list.toXMLString().length));*/
-            
+
             
             list = testInstance.test13();
             assertEquals(list.length(), 4, 'unexpected list length');
             assertEquals(list.toXMLString().length, 506, 'unexpected list content');
-         //   RoyaleUnitTestRunner.consoleOut(list);
-         //   RoyaleUnitTestRunner.consoleOut('13 end -----------------'+list.length()+","+list.toXMLString().length);
+
             list = testInstance.test14();
             assertEquals(list.length(), 5, 'unexpected list length');
             assertEquals(list.toXMLString().length, 618, 'unexpected list content');
             
-           /*
-            RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('14 end -----------------'+list.length()+","+list.toXMLString().length);
-      */
+
         
         }
     
@@ -407,14 +376,12 @@ package flexUnitTests.xml
         
             var url:String = feed.link.(@rel=="self").@href;
         
-          //  RoyaleUnitTestRunner.consoleOut('testUseNamespace::'+feed.link.(@rel=="self").@href);
-          //  RoyaleUnitTestRunner.consoleOut('testUseNamespace::'+url);
+
             assertEquals(url, 'config/blahblah/user/123123customer/443512501473324764966/domain/', 'unexpected query result');
         
             var links:XMLList = feed.link;
             assertEquals(links.toString().length, 581, 'unexpected query result');
-    
-            //RoyaleUnitTestRunner.consoleOut('testUseNamespace::'+links);
+            
             //IE11/Edge failure because of order
             /*assertEquals(links.toString(), '<link rel="self" type="application/atom+xml" href="config/blahblah/user/123123" xmlns="http://www.w3.org/2005/Atom" xmlns:royale="https://royale.apache.org"/>\n' +
                     '<link rel="customer" href="customer/999973324764966" xmlns="http://www.w3.org/2005/Atom" xmlns:royale="https://royale.apache.org"/>\n' +
@@ -429,8 +396,7 @@ package flexUnitTests.xml
         
             var anyLinks:XMLList = xml..*::link;
             assertEquals(anyLinks.length(),5, 'unexpected results from *any* namespace based descendants query');
-            /* RoyaleUnitTestRunner.consoleOut('descendants any * Links');
-             RoyaleUnitTestRunner.consoleOut(anyLinks.toString());*/
+
         }
     
     
@@ -441,29 +407,61 @@ package flexUnitTests.xml
             //public: (seems to behave like 'default')
             var unusualLinks:XMLList = xml..public::link;
             assertEquals(unusualLinks.length(),3, 'unexpected results from public namespace based descendants query');
-            /*   RoyaleUnitTestRunner.consoleOut('descendants public Links');
-               RoyaleUnitTestRunner.consoleOut(unusualLinks.toString());*/
+
         
             //protected: (seems to behave like 'default')
             unusualLinks = xml..protected::link;
         
             assertEquals(unusualLinks.length(),3, 'unexpected results from protected namespace based descendants query');
-            /*RoyaleUnitTestRunner.consoleOut('descendants protected Links');
-            RoyaleUnitTestRunner.consoleOut(unusualLinks.toString());*/
-        
+
             unusualLinks = xml..internal::link;
         
             assertEquals(unusualLinks.length(),0, 'unexpected results from internal namespace based descendants query');
-            /* RoyaleUnitTestRunner.consoleOut('descendants internal Links');
-             RoyaleUnitTestRunner.consoleOut(unusualLinks.toString());*/
-        
+
         
             unusualLinks = xml..private::link;
         
             assertEquals(unusualLinks.length(),0, 'unexpected results from private namespace based descendants query');
-            /* RoyaleUnitTestRunner.consoleOut('descendants private Links');
-             RoyaleUnitTestRunner.consoleOut(unusualLinks.toString());*/
+
+            
+        }
+        
+        [Test]
+        public function testAddingWithNamespace():void{
+            var data:XML =<xml/>;
+            var NS_DEF:Namespace = new Namespace("myNS");
+
+            var param:XML = <param>something</param>;
+
+            var parameters:XML = data.NS_DEF::parameters[0];
+            if (parameters == null) //which it should be
+            {
+                data.NS_DEF::parameters = ""; //<- bad codegen fix
+                parameters = data.NS_DEF::parameters[0];
+            }
+            parameters.appendChild(param);
+
+            assertEquals(data.toXMLString(), '<xml>\n' +
+                    '  <parameters xmlns="myNS">\n' +
+                    '    <param>something</param>\n' +
+                    '  </parameters>\n' +
+                    '</xml>', 'unexpected xml content');
+
+
+
+            var somethingElse:String = 'anything';
+
+            var properties:XML = data.NS_DEF::parameters[0];
+            properties[new QName(NS_DEF.uri, somethingElse)] = 'anythingValue';
             
+            assertEquals(data.toXMLString(), '<xml>\n' +
+                    '  <parameters xmlns="myNS">\n' +
+                    '    <param>something</param>\n' +
+                    '    <anything>anythingValue</anything>\n' +
+                    '  </parameters>\n' +
+                    '</xml>', 'unexpected xml content');
         }
     }
+
+
 }
diff --git a/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLTesterGeneralTest.as b/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLTesterGeneralTest.as
index 2d3e57c..0a7b9a9 100644
--- a/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLTesterGeneralTest.as
+++ b/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLTesterGeneralTest.as
@@ -31,13 +31,13 @@ package flexUnitTests.xml
     {
         public static var isJS:Boolean = COMPILE::JS;
         
-        private var xmlStr:String;
+        private static var xmlStr:String;
         
-        private var quotedXML:XML;
+        private static var quotedXML:XML;
         
-        private var xml:XML;
-        private var text:String;
-        private var xml2:XML;
+        private static var xml:XML;
+        private static var text:String;
+        private static var xml2:XML;
         
         private var settings:Object;
         
@@ -56,6 +56,20 @@ package flexUnitTests.xml
         {
             settings = XML.settings();
             
+
+        }
+        
+        [After]
+        public function tearDown():void
+        {
+
+            
+            XML.setSettings(settings);
+        }
+        
+        [BeforeClass]
+        public static function setUpBeforeClass():void
+        {
             xmlStr ='<?xml version="1.0" encoding="UTF-8" ?>' +
                     '<catalog xmlns:fx="http://ns.adobe.com/mxml/2009"' +
                     '              xmlns:dac="com.printui.view.components.DesignAreaComponents.*">' +
@@ -100,34 +114,22 @@ package flexUnitTests.xml
                     '      </catalog_item>' +
                     '   </product>' +
                     '</catalog>';
-            
+
             quotedXML = <root title="That's Entertainment"/>;
             xml = new XML(xmlStr);
             text = "hi";
             xml2 = new XML('<root xmlns:fz="http://ns.adobe.com/mxml/2009"><a><b/></a><a name="fred"/><a>hi<b>yeah!</b></a><a name="frank"/><c/></root>');
-            
+
         }
         
-        [After]
-        public function tearDown():void
+        [AfterClass]
+        public static function tearDownAfterClass():void
         {
             xmlStr = null;
             quotedXML = null;
             xml = null;
             text = null;
             xml2 = null;
-            
-            XML.setSettings(settings);
-        }
-        
-        [BeforeClass]
-        public static function setUpBeforeClass():void
-        {
-        }
-        
-        [AfterClass]
-        public static function tearDownAfterClass():void
-        {
         }
         
         
@@ -1136,5 +1138,29 @@ package flexUnitTests.xml
             assertEquals(xml.toXMLString(),'<root name="foo"/>',"the first baz element should have been removed.");
             XML.setSettings(XML.defaultSettings());
         }
+
+        [Test]
+        public function testDynamicAttributes():void{
+            var xml:XML = <xml myAtt1="test1" myAtt2="test2"/>;
+
+            assertEquals(xml.attributes().length(),2, 'unexpected attributes count');
+            const MYAtt:String = 'myAtt1';
+            const MYAttTestVal:String = 'myAttTestVal';
+            delete xml.@[MYAtt];
+            assertEquals(xml.attributes().length(),1, 'unexpected attributes count');
+
+            xml.@[MYAtt] = MYAttTestVal;
+            assertEquals(xml.attributes().length(),2, 'unexpected attributes count');
+
+            assertEquals(xml.@myAtt1,'myAttTestVal', 'unexpected attributes value');
+
+        }
+        
+        //@todo - Passes in Swf, fails in browser:
+        /*[Test]
+        public function checkNumericAttributeSupported():void{
+            var xml:XML = XML('<test 1="23"/>');
+            assertEquals(xml.toXMLString(), '<test 1="23"/>', 'roundtripping with numeric attributes did not work');
+        }*/
     }
 }
diff --git a/manualtests/UnitTests/src/main/royale/flexUnitTests/XMLTester.as b/manualtests/UnitTests/src/main/royale/flexUnitTests/XMLTester.as
index 460f423..891daa9 100644
--- a/manualtests/UnitTests/src/main/royale/flexUnitTests/XMLTester.as
+++ b/manualtests/UnitTests/src/main/royale/flexUnitTests/XMLTester.as
@@ -34,19 +34,19 @@ package flexUnitTests
         }
         
         
-        public var xmlTesterGeneralTest:XMLTesterGeneralTest;
+      //  public var xmlTesterGeneralTest:XMLTesterGeneralTest;
         
-        public var xmlTesterStringifyTest:XMLTesterStringifyTest;
+        //public var xmlTesterStringifyTest:XMLTesterStringifyTest;
     
-        public var xmlListTesterGeneralTest:XMLListTesterGeneralTest;
+        //public var xmlListTesterGeneralTest:XMLListTesterGeneralTest;
         
-        public var xmlNamespaceTest:XMLNamespaceTest;
+       // public var xmlNamespaceTest:XMLNamespaceTest;
     
-        public var xmlNamespaceClassTest:XMLNamespaceClassTest;
+        //public var xmlNamespaceClassTest:XMLNamespaceClassTest;
     
         public var xmlQNameTest:XMLQNameTest;
     
-        public var xmlNamespaceQueries:XMLTesterNamespaceQueries;
+       // public var xmlNamespaceQueries:XMLTesterNamespaceQueries;
 
     }
 }
diff --git a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as
index bbfd733..97a1df9 100644
--- a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as
+++ b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as
@@ -189,15 +189,32 @@ package flexUnitTests.xml
             //use length here to account for variation in attribute/namespace sequence outputs
             assertTrue( xmllist.toXMLString().length == 1431, 'XMLList length was unexpected');
         }
-        
+
         [Test]
         public function testWithDecl():void{
-            
+
             var list:XMLList = new XMLList('<?xml version="1.0" encoding="utf-8"?><success>false</success><retryable>false</retryable><localStatus>SESSION_NO_SUCH_CUSTOMER</localStatus>');
             assertEquals(list.length(), 3, 'unexpected parsing result for list content');
-            
+
+        }
+
+        [Test]
+        public function testAssignmentRange():void{
+
+            var list:XMLList = new XMLList('<?xml version="1.0" encoding="utf-8"?><success>false</success><retryable>false</retryable><localStatus>SESSION_NO_SUCH_CUSTOMER</localStatus>');
+            assertEquals(list.length(), 3, 'unexpected parsing result for list content');
+            //out of range index assignment
+            list[10] = <message>You cannot login, please check with tech support</message>;
+
+            assertEquals(list.length(), 4, 'unexpected length result for list content');
+            assertEquals(list[3].toXMLString(),'<message>You cannot login, please check with tech support</message>', 'unexpected list content' );
+            var hadError:Boolean;
+            try{
+                list.@attr = 'testAtt'
+            } catch (e:Error) {
+                hadError = true;
+            }
+            assertTrue(hadError, 'expected an error');
         }
-        
-        
     }
 }
diff --git a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLNamespaceTest.as b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLNamespaceTest.as
index b7a6d74..689507b 100644
--- a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLNamespaceTest.as
+++ b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLNamespaceTest.as
@@ -108,7 +108,7 @@ package flexUnitTests.xml
         public function testMinimalDefault():void{
             default xml namespace = 'test';
             var xml:XML = <root/>;
-    
+            
             var ns:Namespace = xml.namespace();
             var playerVersion:Number = getPlayerVersion();
             //account for what appears to be a player bug in a range of player versions (not verified on Mac)
@@ -116,14 +116,15 @@ package flexUnitTests.xml
             var permitEmptyString:Boolean  = playerVersion >= 11.2 && playerVersion <= 20.0;
             var prefix:* = ns.prefix;
             var testIsOK:Boolean = permitEmptyString ? prefix === '' || prefix === undefined : prefix === undefined;
+            
             //assertStrictlyEquals(ns.prefix, undefined, 'unexpected prefix value ');
             assertTrue(testIsOK, 'unexpected prefix value ');
-    
+            
             var uri:String = ns.uri;
             testIsOK = permitEmptyString ? uri == '' || uri == 'test' : uri == 'test';
             //assertEquals(ns.uri, 'test', 'unexpected uri value from specific default namespace');
             assertTrue(testIsOK, 'unexpected uri value from specific default namespace');
-    
+            
             //try top level function
             xml = XML('<root/>');
             ns= xml.namespace();
@@ -135,7 +136,6 @@ package flexUnitTests.xml
             testIsOK = permitEmptyString ? uri == '' || uri == 'test' : uri == 'test';
             //assertEquals(ns.uri, 'test', 'unexpected uri value from specific default namespace');
             assertTrue(testIsOK, 'unexpected uri value from specific default namespace');
-            
         }
         
     
@@ -169,12 +169,6 @@ package flexUnitTests.xml
         
         
         
-        //private var atom:Namespace = ATOM_NS;
-        
-        
-        
-        
-        
         
         
         [Test]
@@ -185,13 +179,10 @@ package flexUnitTests.xml
             var atomLinks:XMLList = xml.rss.channel.atom::link;
             assertEquals(atomLinks.length(),2, 'unexpected results from namespace based child query');
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
-            RoyaleUnitTestRunner.consoleOut(atomLinks.toString());
+          //  RoyaleUnitTestRunner.consoleOut(atomLinks.toString());
             assertEquals(atomLinks.toString().length, 459, 'unexpected list content length');
             
-            /*RoyaleUnitTestRunner.consoleOut('atomLinks');
-            RoyaleUnitTestRunner.consoleOut(atomLinks.toString());
-            RoyaleUnitTestRunner.consoleOut(atomLinks.toString().length+'');*/
-            
+
         }
     
     
@@ -202,13 +193,10 @@ package flexUnitTests.xml
             var atomLinks:XMLList = xml..atom::link;
             assertEquals(atomLinks.length(),2, 'unexpected results from namespace based child query');
             //account for browser DOMParser variation to order of 'attributes' - use length comparison
-           // RoyaleUnitTestRunner.consoleOut(atomLinks.toString());
+
             assertEquals(atomLinks.toString().length, 459, 'unexpected list content length');
       
-            /*RoyaleUnitTestRunner.consoleOut('descendants atomLinks');
-            RoyaleUnitTestRunner.consoleOut(atomLinks.toString());
-            RoyaleUnitTestRunner.consoleOut(atomLinks.toString().length+'');*/
-            
+
         }
     
         [Test]
@@ -231,10 +219,7 @@ package flexUnitTests.xml
             assertEquals(inscopes.length, 2, 'unexpected namespace count');
             //account for browser DOMParser variation to order of 'attributes' - use length comparison
             assertEquals(inscopes.toString().length, 'http://www.w3.org/2005/Atom,nothing'.length, 'unexpected namespace content');
-           /* RoyaleUnitTestRunner.consoleOut(inscopes.length+":"+inscopes.toString());
-            for each(var ns:Namespace in inscopes) {
-                RoyaleUnitTestRunner.consoleOut('prefix:\''+ns.prefix+'\', '+ns.uri);
-            }*/
+
             
             var links:XMLList = feed.atom::link;
             var link1:XML = links[0];
@@ -244,10 +229,7 @@ package flexUnitTests.xml
             assertEquals(inscopes.length, 3, 'unexpected namespace count');
             //account for browser DOMParser variation to order of 'attributes' - use length comparison
             assertEquals(inscopes.toString().length, 'blah,http://www.w3.org/2005/Atom,nothing'.length, 'unexpected namespace content');
-           /* RoyaleUnitTestRunner.consoleOut(inscopes.length+":"+inscopes.toString());
-            for each(var ns:Namespace in inscopes) {
-                RoyaleUnitTestRunner.consoleOut('prefix:\''+ns.prefix+'\', '+ns.uri);
-            }*/
+
         }
     
         [Test]
@@ -328,20 +310,14 @@ package flexUnitTests.xml
             
 
             list = testInstance.test2();
-           /* RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('2 end -----------------'+list.length());
-            RoyaleUnitTestRunner.consoleOut(String(list.toXMLString().length));*/
-    
+
             assertEquals(list.length(), 5, 'unexpected list length');
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
             assertEquals(list.toXMLString().length, 572, 'unexpected list content');
             
             
             list = testInstance.test3();
-           /* RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('3 end -----------------'+list.length());
-            RoyaleUnitTestRunner.consoleOut(String(list.toXMLString().length));*/
-    
+
             assertEquals(list.length(), 4, 'unexpected list length');
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
             assertEquals(list.toXMLString().length, 466, 'unexpected list content');
@@ -349,10 +325,7 @@ package flexUnitTests.xml
     
           
             list = testInstance.test4();
-            /*RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('4 end -----------------'+list.length());
-            RoyaleUnitTestRunner.consoleOut(String(list.toXMLString().length));*/
-    
+
             assertEquals(list.length(), 4, 'unexpected list length');
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
             assertEquals(list.toXMLString().length, 466, 'unexpected list content');
@@ -363,33 +336,22 @@ package flexUnitTests.xml
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
             assertEquals(list.toXMLString().length, 618, 'unexpected list content');
             
-           /* RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('11 end -----------------'+list.length());
-            RoyaleUnitTestRunner.consoleOut(String(list.toXMLString().length));*/
-            
-            
+
             list = testInstance.test12();
             assertEquals(list.length(), 6, 'unexpected list length');
             //account for browser DOMParser variation to order of 'attrributes' - use length comparison
             assertEquals(list.toXMLString().length, 729, 'unexpected list content');
-           /* RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('12 end -----------------'+list.length());
-            RoyaleUnitTestRunner.consoleOut(String(list.toXMLString().length));*/
-            
+
             
             list = testInstance.test13();
             assertEquals(list.length(), 4, 'unexpected list length');
             assertEquals(list.toXMLString().length, 506, 'unexpected list content');
-         //   RoyaleUnitTestRunner.consoleOut(list);
-         //   RoyaleUnitTestRunner.consoleOut('13 end -----------------'+list.length()+","+list.toXMLString().length);
+
             list = testInstance.test14();
             assertEquals(list.length(), 5, 'unexpected list length');
             assertEquals(list.toXMLString().length, 618, 'unexpected list content');
             
-           /*
-            RoyaleUnitTestRunner.consoleOut(list);
-            RoyaleUnitTestRunner.consoleOut('14 end -----------------'+list.length()+","+list.toXMLString().length);
-      */
+
         
         }
     
@@ -413,14 +375,12 @@ package flexUnitTests.xml
         
             var url:String = feed.link.(@rel=="self").@href;
         
-            RoyaleUnitTestRunner.consoleOut('testUseNamespace::'+feed.link.(@rel=="self").@href);
-            RoyaleUnitTestRunner.consoleOut('testUseNamespace::'+url);
+
             assertEquals(url, 'config/blahblah/user/123123customer/443512501473324764966/domain/', 'unexpected query result');
         
             var links:XMLList = feed.link;
             assertEquals(links.toString().length, 581, 'unexpected query result');
-    
-            //RoyaleUnitTestRunner.consoleOut('testUseNamespace::'+links);
+            
             //IE11/Edge failure because of order
             /*assertEquals(links.toString(), '<link rel="self" type="application/atom+xml" href="config/blahblah/user/123123" xmlns="http://www.w3.org/2005/Atom" xmlns:royale="https://royale.apache.org"/>\n' +
                     '<link rel="customer" href="customer/999973324764966" xmlns="http://www.w3.org/2005/Atom" xmlns:royale="https://royale.apache.org"/>\n' +
@@ -435,8 +395,7 @@ package flexUnitTests.xml
         
             var anyLinks:XMLList = xml..*::link;
             assertEquals(anyLinks.length(),5, 'unexpected results from *any* namespace based descendants query');
-            /* RoyaleUnitTestRunner.consoleOut('descendants any * Links');
-             RoyaleUnitTestRunner.consoleOut(anyLinks.toString());*/
+
         }
     
     
@@ -447,29 +406,61 @@ package flexUnitTests.xml
             //public: (seems to behave like 'default')
             var unusualLinks:XMLList = xml..public::link;
             assertEquals(unusualLinks.length(),3, 'unexpected results from public namespace based descendants query');
-            /*   RoyaleUnitTestRunner.consoleOut('descendants public Links');
-               RoyaleUnitTestRunner.consoleOut(unusualLinks.toString());*/
+
         
             //protected: (seems to behave like 'default')
             unusualLinks = xml..protected::link;
         
             assertEquals(unusualLinks.length(),3, 'unexpected results from protected namespace based descendants query');
-            /*RoyaleUnitTestRunner.consoleOut('descendants protected Links');
-            RoyaleUnitTestRunner.consoleOut(unusualLinks.toString());*/
-        
+
             unusualLinks = xml..internal::link;
         
             assertEquals(unusualLinks.length(),0, 'unexpected results from internal namespace based descendants query');
-            /* RoyaleUnitTestRunner.consoleOut('descendants internal Links');
-             RoyaleUnitTestRunner.consoleOut(unusualLinks.toString());*/
-        
+
         
             unusualLinks = xml..private::link;
         
             assertEquals(unusualLinks.length(),0, 'unexpected results from private namespace based descendants query');
-            /* RoyaleUnitTestRunner.consoleOut('descendants private Links');
-             RoyaleUnitTestRunner.consoleOut(unusualLinks.toString());*/
+
+            
+        }
         
+        [Test]
+        public function testAddingWithNamespace():void{
+            var data:XML =<xml/>;
+            var NS_DEF:Namespace = new Namespace("myNS");
+
+            var param:XML = <param>something</param>;
+
+            var parameters:XML = data.NS_DEF::parameters[0];
+            if (parameters == null) //which it should be
+            {
+                data.NS_DEF::parameters = ""; //<- bad codegen fix
+                parameters = data.NS_DEF::parameters[0];
+            }
+            parameters.appendChild(param);
+
+            assertEquals(data.toXMLString(), '<xml>\n' +
+                    '  <parameters xmlns="myNS">\n' +
+                    '    <param>something</param>\n' +
+                    '  </parameters>\n' +
+                    '</xml>', 'unexpected xml content');
+
+
+
+            var somethingElse:String = 'anything';
+
+            var properties:XML = data.NS_DEF::parameters[0];
+            properties[new QName(NS_DEF.uri, somethingElse)] = 'anythingValue';
+            
+            assertEquals(data.toXMLString(), '<xml>\n' +
+                    '  <parameters xmlns="myNS">\n' +
+                    '    <param>something</param>\n' +
+                    '    <anything>anythingValue</anything>\n' +
+                    '  </parameters>\n' +
+                    '</xml>', 'unexpected xml content');
         }
     }
+
+
 }
diff --git a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as
index 0c4b921..2f2118a 100644
--- a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as
+++ b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as
@@ -21,8 +21,10 @@ package flexUnitTests.xml
     
     
     import org.apache.royale.test.asserts.*;
-    
-    //import testshim.RoyaleUnitTestRunner;
+
+import testshim.RoyaleUnitTestRunner;
+
+//import testshim.RoyaleUnitTestRunner;
     
     /**
      * @royalesuppresspublicvarwarning
@@ -1124,7 +1126,39 @@ package flexUnitTests.xml
     
             XML.setSettings(XML.defaultSettings());
         }
-        
+
+        [Test]
+        public function testDelete():void{
+            XML.setSettings(XML.defaultSettings());
+            XML.prettyPrinting = false;
+            var xml:XML = <root name="foo"><baz name="baz1"/><baz name="baz2"/></root>;
+            delete xml.@name;
+            assertEquals(xml.toString(),'<root><baz name="baz1"/><baz name="baz2"/></root>',"name attribute should have been removed.");
+            delete xml.baz[0];
+            assertEquals(xml.toString(),'<root><baz name="baz2"/></root>',"the first baz element should have been removed.");
+            xml = <root name="foo"><baz name="baz1"/><baz name="baz2"/></root>;
+            delete xml.baz;
+            // delete xml.baz[0];
+            assertEquals(xml.toXMLString(),'<root name="foo"/>',"the first baz element should have been removed.");
+            XML.setSettings(XML.defaultSettings());
+        }
+
+        [Test]
+        public function testDynamicAttributes():void{
+            var xml:XML = <xml myAtt1="test1" myAtt2="test2"/>;
+
+            assertEquals(xml.attributes().length(),2, 'unexpected attributes count');
+            const MYAtt:String = 'myAtt1';
+            const MYAttTestVal:String = 'myAttTestVal';
+            delete xml.@[MYAtt];
+            assertEquals(xml.attributes().length(),1, 'unexpected attributes count');
+
+            xml.@[MYAtt] = MYAttTestVal;
+            assertEquals(xml.attributes().length(),2, 'unexpected attributes count');
+
+            assertEquals(xml.@myAtt1,'myAttTestVal', 'unexpected attributes value');
+
+        }
         
         //@todo - Passes in Swf, fails in browser:
         /*[Test]