RPC: arguments/request tags are now parsed the same as <fx:Model>

Nested objects and attributes for fields are now supported.

This brings the Royale compiler closer in compatibility to the Flex SDK compiler.
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLHTTPServiceRequestPropertyNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLHTTPServiceRequestPropertyNode.java
index d519cc7..e4f077d 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLHTTPServiceRequestPropertyNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLHTTPServiceRequestPropertyNode.java
@@ -20,17 +20,16 @@
 package org.apache.royale.compiler.internal.tree.mxml;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.internal.projects.RoyaleProject;
 import org.apache.royale.compiler.mxml.IMXMLTagData;
-import org.apache.royale.compiler.mxml.IMXMLUnitData;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLHTTPServiceRequestPropertyNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLModelPropertyContainerNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLModelPropertyNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLNode;
 
 /**
@@ -86,53 +85,13 @@
 
         MXMLNodeInfo info = createNodeInfo(builder);
 
-        
+        // parse it like <fx:Model>, but convert to property specifiers
+        MXMLModelRootNode modelRootNode = new MXMLModelRootNode(this);
+        modelRootNode.initializeFromTag(builder, tag);
 
-        // look for duplicate property tags
-        // if there's more than one of the same tag, the value will be an array
-        Map<String, List<IMXMLTagData>> propertyNameToTags = new HashMap<>();
-        for (IMXMLUnitData unit = tag.getFirstChildUnit(); unit != null; unit = unit.getNextSiblingUnit())
+        final RoyaleProject project = builder.getProject();
+        for (MXMLPropertySpecifierNode specifierNode : getPropertySpecifiers(builder, modelRootNode, objectNode, this, project))
         {
-            if (unit instanceof IMXMLTagData)
-            {
-                IMXMLTagData childTag = (IMXMLTagData) unit;
-                String propertyName = childTag.getShortName();
-                List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName);
-                if (tagsForProperty == null)
-                {
-                    tagsForProperty = new ArrayList<IMXMLTagData>();
-                    propertyNameToTags.put(propertyName, tagsForProperty);
-                }
-                tagsForProperty.add(childTag);
-            }
-        }
-
-        // for each property found, initialize its tags
-        for (String propertyName : propertyNameToTags.keySet())
-        {
-            final List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName);
-            final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(this);
-            specifierNode.setDynamicName(propertyName);
-            if (tagsForProperty.size() > 1)
-            {
-                List<IMXMLNode> argsChildNodes = new ArrayList<IMXMLNode>();
-                for (IMXMLTagData childTag : tagsForProperty)
-                {
-                    final MXMLPropertySpecifierNode childSpecifierNode = new MXMLPropertySpecifierNode(this);
-                    childSpecifierNode.setDynamicName(propertyName);
-                    childSpecifierNode.initializeFromTag(builder, childTag);
-                    argsChildNodes.add(childSpecifierNode.getInstanceNode());
-                }
-
-                MXMLArrayNode argsArrayNode = new MXMLArrayNode(objectNode);
-                argsArrayNode.setChildren(argsChildNodes.toArray(new IMXMLNode[0]));
-                specifierNode.setInstanceNode(argsArrayNode);
-            }
-            else
-            {
-                specifierNode.initializeFromTag(builder, tagsForProperty.get(0));
-            }
-            specifierNode.setParent(objectNode);
             info.addChildNode(specifierNode);
         }
 
@@ -140,6 +99,72 @@
         initializationComplete(builder, tag, info);
     }
 
+    protected MXMLPropertySpecifierNode[] getPropertySpecifiers(MXMLTreeBuilder builder, IMXMLModelPropertyContainerNode containerNode, MXMLObjectNode parentNode, MXMLPropertySpecifierNode parentSpecifierNode, RoyaleProject project)
+    {
+        List<MXMLPropertySpecifierNode> propSpecifiers = new ArrayList<MXMLPropertySpecifierNode>();
+        for (String propertyName : containerNode.getPropertyNames()) {
+            IMXMLModelPropertyNode[] propertyNodes = containerNode.getPropertyNodes(propertyName);
+            MXMLPropertySpecifierNode specifierNode = getPropertySpecifier(builder, propertyName, propertyNodes, parentNode, parentSpecifierNode, project);
+            propSpecifiers.add(specifierNode);
+        }
+        return propSpecifiers.toArray(new MXMLPropertySpecifierNode[0]);
+    }
+
+    protected MXMLPropertySpecifierNode getPropertySpecifier(MXMLTreeBuilder builder, String propertyName, IMXMLModelPropertyNode[] propertyNodes, MXMLObjectNode parentNode, MXMLPropertySpecifierNode parentSpecifierNode, RoyaleProject project)
+    {
+        final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(parentNode);
+        specifierNode.setDynamicName(propertyName);
+        if (propertyNodes.length > 1)
+        {
+            MXMLArrayNode argsArrayNode = new MXMLArrayNode(this);
+            argsArrayNode.setClassReference(project, IASLanguageConstants.Array);
+
+            List<IMXMLNode> argsChildNodes = new ArrayList<IMXMLNode>();
+            for (IMXMLModelPropertyNode propNode : propertyNodes)
+            {
+                if (propNode.hasLeafValue())
+                {
+                    MXMLInstanceNode propInstanceNode = (MXMLInstanceNode) propNode.getInstanceNode();
+                    propInstanceNode.setParent(argsArrayNode);
+                    argsChildNodes.add(propInstanceNode);
+                }
+                else
+                {
+                    MXMLObjectNode propObjectNode = new MXMLObjectNode(this);
+                    propObjectNode.setLocation(propNode);
+                    propObjectNode.setClassReference(project, IASLanguageConstants.Object);
+                    MXMLPropertySpecifierNode[] propSpecifiers = getPropertySpecifiers(builder, propNode, propObjectNode, specifierNode, project);
+                    propObjectNode.setChildren(propSpecifiers);
+                    argsChildNodes.add(propObjectNode);
+                }
+            }
+
+            argsArrayNode.setChildren(argsChildNodes.toArray(new IMXMLNode[0]));
+            specifierNode.setInstanceNode(argsArrayNode);
+        }
+        else
+        {
+            IMXMLModelPropertyNode propNode = propertyNodes[0];
+            if (propNode.hasLeafValue())
+            {
+                MXMLInstanceNode propInstanceNode = (MXMLInstanceNode) propNode.getInstanceNode();
+                propInstanceNode.setParent(parentSpecifierNode);
+                specifierNode.setLocation(propNode);
+                specifierNode.setInstanceNode(propInstanceNode);
+            }
+            else
+            {
+                MXMLObjectNode propObjectNode = new MXMLObjectNode(this);
+                propObjectNode.setLocation(propNode);
+                propObjectNode.setClassReference(project, IASLanguageConstants.Object);
+                MXMLPropertySpecifierNode[] propSpecifiers = getPropertySpecifiers(builder, propNode, propObjectNode, specifierNode, project);
+                propObjectNode.setChildren(propSpecifiers);
+                specifierNode.setInstanceNode(propObjectNode);
+            }
+        }
+        return specifierNode;
+    }
+
     /**
      * Synthesize an "instance" node of type "Object" to own all the request
      * fields.
@@ -161,5 +186,6 @@
         final RoyaleProject project = builder.getProject();
         objectNode.setClassReference(project, IASLanguageConstants.Object);
         objectNode.setChildren(info.getChildNodeList().toArray(new IMXMLNode[0]));
+        objectNode.setLocation(tag);
     }
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLRemoteObjectMethodArgumentsPropertyNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLRemoteObjectMethodArgumentsPropertyNode.java
index 52da032..c472276 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLRemoteObjectMethodArgumentsPropertyNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLRemoteObjectMethodArgumentsPropertyNode.java
@@ -20,16 +20,15 @@
 package org.apache.royale.compiler.internal.tree.mxml;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.internal.projects.RoyaleProject;
 import org.apache.royale.compiler.mxml.IMXMLTagData;
-import org.apache.royale.compiler.mxml.IMXMLUnitData;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLModelPropertyContainerNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLModelPropertyNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLRemoteObjectMethodArgumentsPropertyNode;
 
@@ -86,51 +85,13 @@
 
         MXMLNodeInfo info = createNodeInfo(builder);
 
-        // look for duplicate property tags
-        // if there's more than one of the same tag, the value will be an array
-        Map<String, List<IMXMLTagData>> propertyNameToTags = new HashMap<>();
-        for (IMXMLUnitData unit = tag.getFirstChildUnit(); unit != null; unit = unit.getNextSiblingUnit())
-        {
-            if (unit instanceof IMXMLTagData)
-            {
-                IMXMLTagData childTag = (IMXMLTagData) unit;
-                String propertyName = childTag.getShortName();
-                List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName);
-                if (tagsForProperty == null)
-                {
-                    tagsForProperty = new ArrayList<IMXMLTagData>();
-                    propertyNameToTags.put(propertyName, tagsForProperty);
-                }
-                tagsForProperty.add(childTag);
-            }
-        }
+        // parse it like <fx:Model>, but convert to property specifiers
+        MXMLModelRootNode modelRootNode = new MXMLModelRootNode(this);
+        modelRootNode.initializeFromTag(builder, tag);
 
-        // for each property found, initialize its tags
-        for (String propertyName : propertyNameToTags.keySet())
+        final RoyaleProject project = builder.getProject();
+        for (MXMLPropertySpecifierNode specifierNode : getPropertySpecifiers(builder, modelRootNode, objectNode, this, project))
         {
-            final List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName);
-            final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(this);
-            specifierNode.setDynamicName(propertyName);
-            if (tagsForProperty.size() > 1)
-            {
-                List<IMXMLNode> argsChildNodes = new ArrayList<IMXMLNode>();
-                for (IMXMLTagData childTag : tagsForProperty)
-                {
-                    final MXMLPropertySpecifierNode childSpecifierNode = new MXMLPropertySpecifierNode(this);
-                    childSpecifierNode.setDynamicName(propertyName);
-                    childSpecifierNode.initializeFromTag(builder, childTag);
-                    argsChildNodes.add(childSpecifierNode.getInstanceNode());
-                }
-
-                MXMLArrayNode argsArrayNode = new MXMLArrayNode(objectNode);
-                argsArrayNode.setChildren(argsChildNodes.toArray(new IMXMLNode[0]));
-                specifierNode.setInstanceNode(argsArrayNode);
-            }
-            else
-            {
-                specifierNode.initializeFromTag(builder, tagsForProperty.get(0));
-            }
-            specifierNode.setParent(objectNode);
             info.addChildNode(specifierNode);
         }
 
@@ -138,6 +99,72 @@
         initializationComplete(builder, tag, info);
     }
 
+    protected MXMLPropertySpecifierNode[] getPropertySpecifiers(MXMLTreeBuilder builder, IMXMLModelPropertyContainerNode containerNode, MXMLObjectNode parentNode, MXMLPropertySpecifierNode parentSpecifierNode, RoyaleProject project)
+    {
+        List<MXMLPropertySpecifierNode> propSpecifiers = new ArrayList<MXMLPropertySpecifierNode>();
+        for (String propertyName : containerNode.getPropertyNames()) {
+            IMXMLModelPropertyNode[] propertyNodes = containerNode.getPropertyNodes(propertyName);
+            MXMLPropertySpecifierNode specifierNode = getPropertySpecifier(builder, propertyName, propertyNodes, parentNode, parentSpecifierNode, project);
+            propSpecifiers.add(specifierNode);
+        }
+        return propSpecifiers.toArray(new MXMLPropertySpecifierNode[0]);
+    }
+
+    protected MXMLPropertySpecifierNode getPropertySpecifier(MXMLTreeBuilder builder, String propertyName, IMXMLModelPropertyNode[] propertyNodes, MXMLObjectNode parentNode, MXMLPropertySpecifierNode parentSpecifierNode, RoyaleProject project)
+    {
+        final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(parentNode);
+        specifierNode.setDynamicName(propertyName);
+        if (propertyNodes.length > 1)
+        {
+            MXMLArrayNode argsArrayNode = new MXMLArrayNode(this);
+            argsArrayNode.setClassReference(project, IASLanguageConstants.Array);
+
+            List<IMXMLNode> argsChildNodes = new ArrayList<IMXMLNode>();
+            for (IMXMLModelPropertyNode propNode : propertyNodes)
+            {
+                if (propNode.hasLeafValue())
+                {
+                    MXMLInstanceNode propInstanceNode = (MXMLInstanceNode) propNode.getInstanceNode();
+                    propInstanceNode.setParent(argsArrayNode);
+                    argsChildNodes.add(propInstanceNode);
+                }
+                else
+                {
+                    MXMLObjectNode propObjectNode = new MXMLObjectNode(this);
+                    propObjectNode.setLocation(propNode);
+                    propObjectNode.setClassReference(project, IASLanguageConstants.Object);
+                    MXMLPropertySpecifierNode[] propSpecifiers = getPropertySpecifiers(builder, propNode, propObjectNode, specifierNode, project);
+                    propObjectNode.setChildren(propSpecifiers);
+                    argsChildNodes.add(propObjectNode);
+                }
+            }
+
+            argsArrayNode.setChildren(argsChildNodes.toArray(new IMXMLNode[0]));
+            specifierNode.setInstanceNode(argsArrayNode);
+        }
+        else
+        {
+            IMXMLModelPropertyNode propNode = propertyNodes[0];
+            if (propNode.hasLeafValue())
+            {
+                MXMLInstanceNode propInstanceNode = (MXMLInstanceNode) propNode.getInstanceNode();
+                propInstanceNode.setParent(parentSpecifierNode);
+                specifierNode.setLocation(propNode);
+                specifierNode.setInstanceNode(propInstanceNode);
+            }
+            else
+            {
+                MXMLObjectNode propObjectNode = new MXMLObjectNode(this);
+                propObjectNode.setLocation(propNode);
+                propObjectNode.setClassReference(project, IASLanguageConstants.Object);
+                MXMLPropertySpecifierNode[] propSpecifiers = getPropertySpecifiers(builder, propNode, propObjectNode, specifierNode, project);
+                propObjectNode.setChildren(propSpecifiers);
+                specifierNode.setInstanceNode(propObjectNode);
+            }
+        }
+        return specifierNode;
+    }
+
     /**
      * Synthesize an "instance" node of type "Object" to own all the arguments
      * fields.
@@ -159,5 +186,6 @@
         final RoyaleProject project = builder.getProject();
         objectNode.setClassReference(project, IASLanguageConstants.Object);
         objectNode.setChildren(info.getChildNodeList().toArray(new IMXMLNode[0]));
+        objectNode.setLocation(tag);
     }
 }
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLWebServiceOperationArgumentsPropertyNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLWebServiceOperationArgumentsPropertyNode.java
index e75a9d4..af1380c 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLWebServiceOperationArgumentsPropertyNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLWebServiceOperationArgumentsPropertyNode.java
@@ -20,18 +20,17 @@
 package org.apache.royale.compiler.internal.tree.mxml;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.internal.projects.RoyaleProject;
 import org.apache.royale.compiler.mxml.IMXMLTagData;
-import org.apache.royale.compiler.mxml.IMXMLUnitData;
 import org.apache.royale.compiler.tree.ASTNodeID;
 import org.apache.royale.compiler.tree.as.IASNode;
-import org.apache.royale.compiler.tree.mxml.IMXMLWebServiceOperationArgumentsPropertyNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLModelPropertyContainerNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLModelPropertyNode;
 import org.apache.royale.compiler.tree.mxml.IMXMLNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLWebServiceOperationArgumentsPropertyNode;
 
 /**
  * AST node for the {@code <arguments>} tag under the {@code <operation>} tag, which is under the {@code <WebService>} tag.
@@ -86,51 +85,13 @@
 
         MXMLNodeInfo info = createNodeInfo(builder);
 
-        // look for duplicate property tags
-        // if there's more than one of the same tag, the value will be an array
-        Map<String, List<IMXMLTagData>> propertyNameToTags = new HashMap<>();
-        for (IMXMLUnitData unit = tag.getFirstChildUnit(); unit != null; unit = unit.getNextSiblingUnit())
-        {
-            if (unit instanceof IMXMLTagData)
-            {
-                IMXMLTagData childTag = (IMXMLTagData) unit;
-                String propertyName = childTag.getShortName();
-                List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName);
-                if (tagsForProperty == null)
-                {
-                    tagsForProperty = new ArrayList<IMXMLTagData>();
-                    propertyNameToTags.put(propertyName, tagsForProperty);
-                }
-                tagsForProperty.add(childTag);
-            }
-        }
+        // parse it like <fx:Model>, but convert to property specifiers
+        MXMLModelRootNode modelRootNode = new MXMLModelRootNode(this);
+        modelRootNode.initializeFromTag(builder, tag);
 
-        // for each property found, initialize its tags
-        for (String propertyName : propertyNameToTags.keySet())
+        final RoyaleProject project = builder.getProject();
+        for (MXMLPropertySpecifierNode specifierNode : getPropertySpecifiers(builder, modelRootNode, objectNode, this, project))
         {
-            final List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName);
-            final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(this);
-            specifierNode.setDynamicName(propertyName);
-            if (tagsForProperty.size() > 1)
-            {
-                List<IMXMLNode> argsChildNodes = new ArrayList<IMXMLNode>();
-                for (IMXMLTagData childTag : tagsForProperty)
-                {
-                    final MXMLPropertySpecifierNode childSpecifierNode = new MXMLPropertySpecifierNode(this);
-                    childSpecifierNode.setDynamicName(propertyName);
-                    childSpecifierNode.initializeFromTag(builder, childTag);
-                    argsChildNodes.add(childSpecifierNode.getInstanceNode());
-                }
-
-                MXMLArrayNode argsArrayNode = new MXMLArrayNode(objectNode);
-                argsArrayNode.setChildren(argsChildNodes.toArray(new IMXMLNode[0]));
-                specifierNode.setInstanceNode(argsArrayNode);
-            }
-            else
-            {
-                specifierNode.initializeFromTag(builder, tagsForProperty.get(0));
-            }
-            specifierNode.setParent(objectNode);
             info.addChildNode(specifierNode);
         }
 
@@ -138,6 +99,72 @@
         initializationComplete(builder, tag, info);
     }
 
+    protected MXMLPropertySpecifierNode[] getPropertySpecifiers(MXMLTreeBuilder builder, IMXMLModelPropertyContainerNode containerNode, MXMLObjectNode parentNode, MXMLPropertySpecifierNode parentSpecifierNode, RoyaleProject project)
+    {
+        List<MXMLPropertySpecifierNode> propSpecifiers = new ArrayList<MXMLPropertySpecifierNode>();
+        for (String propertyName : containerNode.getPropertyNames()) {
+            IMXMLModelPropertyNode[] propertyNodes = containerNode.getPropertyNodes(propertyName);
+            MXMLPropertySpecifierNode specifierNode = getPropertySpecifier(builder, propertyName, propertyNodes, parentNode, parentSpecifierNode, project);
+            propSpecifiers.add(specifierNode);
+        }
+        return propSpecifiers.toArray(new MXMLPropertySpecifierNode[0]);
+    }
+
+    protected MXMLPropertySpecifierNode getPropertySpecifier(MXMLTreeBuilder builder, String propertyName, IMXMLModelPropertyNode[] propertyNodes, MXMLObjectNode parentNode, MXMLPropertySpecifierNode parentSpecifierNode, RoyaleProject project)
+    {
+        final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(parentNode);
+        specifierNode.setDynamicName(propertyName);
+        if (propertyNodes.length > 1)
+        {
+            MXMLArrayNode argsArrayNode = new MXMLArrayNode(this);
+            argsArrayNode.setClassReference(project, IASLanguageConstants.Array);
+
+            List<IMXMLNode> argsChildNodes = new ArrayList<IMXMLNode>();
+            for (IMXMLModelPropertyNode propNode : propertyNodes)
+            {
+                if (propNode.hasLeafValue())
+                {
+                    MXMLInstanceNode propInstanceNode = (MXMLInstanceNode) propNode.getInstanceNode();
+                    propInstanceNode.setParent(argsArrayNode);
+                    argsChildNodes.add(propInstanceNode);
+                }
+                else
+                {
+                    MXMLObjectNode propObjectNode = new MXMLObjectNode(this);
+                    propObjectNode.setLocation(propNode);
+                    propObjectNode.setClassReference(project, IASLanguageConstants.Object);
+                    MXMLPropertySpecifierNode[] propSpecifiers = getPropertySpecifiers(builder, propNode, propObjectNode, specifierNode, project);
+                    propObjectNode.setChildren(propSpecifiers);
+                    argsChildNodes.add(propObjectNode);
+                }
+            }
+
+            argsArrayNode.setChildren(argsChildNodes.toArray(new IMXMLNode[0]));
+            specifierNode.setInstanceNode(argsArrayNode);
+        }
+        else
+        {
+            IMXMLModelPropertyNode propNode = propertyNodes[0];
+            if (propNode.hasLeafValue())
+            {
+                MXMLInstanceNode propInstanceNode = (MXMLInstanceNode) propNode.getInstanceNode();
+                propInstanceNode.setParent(parentSpecifierNode);
+                specifierNode.setLocation(propNode);
+                specifierNode.setInstanceNode(propInstanceNode);
+            }
+            else
+            {
+                MXMLObjectNode propObjectNode = new MXMLObjectNode(this);
+                propObjectNode.setLocation(propNode);
+                propObjectNode.setClassReference(project, IASLanguageConstants.Object);
+                MXMLPropertySpecifierNode[] propSpecifiers = getPropertySpecifiers(builder, propNode, propObjectNode, specifierNode, project);
+                propObjectNode.setChildren(propSpecifiers);
+                specifierNode.setInstanceNode(propObjectNode);
+            }
+        }
+        return specifierNode;
+    }
+
     /**
      * Synthesize an "instance" node of type "Object" to own all the arguments
      * fields.
@@ -159,5 +186,6 @@
         final RoyaleProject project = builder.getProject();
         objectNode.setClassReference(project, IASLanguageConstants.Object);
         objectNode.setChildren(info.getChildNodeList().toArray(new IMXMLNode[0]));
+        objectNode.setLocation(tag);
     }
 }
diff --git a/compiler/src/test/java/mxml/tags/MXMLHTTPServiceTagTests.java b/compiler/src/test/java/mxml/tags/MXMLHTTPServiceTagTests.java
index 4984a15..b9e4618 100644
--- a/compiler/src/test/java/mxml/tags/MXMLHTTPServiceTagTests.java
+++ b/compiler/src/test/java/mxml/tags/MXMLHTTPServiceTagTests.java
@@ -98,6 +98,13 @@
     		"        <d>456.7</d>",
     		"        <d>hello</d>",
     		"        <d>true</d>",
+    		"        <e>",
+    		"            <e_1>890.1</e_1>",
+            "        </e>",
+    		"        <f f_1='234.5'/>",
+    		"        <g g_1='howdy'>",
+    		"            <g_1>678.9</g_1>",
+            "        </g>",
     		"    </mx:request>",
     		"    <mx:method>POST</mx:method>",
     		"</mx:HTTPService>"
@@ -113,6 +120,11 @@
             "assertEqual('hs1.request.d[0]', hs1.request['d'][0], 456.7);",
             "assertEqual('hs1.request.d[1]', hs1.request['d'][1], 'hello');",
             "assertEqual('hs1.request.d[2]', hs1.request['d'][2], true);",
+            "assertEqual('hs1.request.e.e_1', hs1.request['e']['e_1'], 890.1);",
+            "assertEqual('hs1.request.f.f_1', hs1.request['f']['f_1'], 234.5);",
+            "assertEqual('hs1.request.g.g_1.length', hs1.request['g']['g_1'].length, 2);",
+            "assertEqual('hs1.request.g.g_1[0]', hs1.request['g']['g_1'][0], 'howdy');",
+            "assertEqual('hs1.request.g.g_1[1]', hs1.request['g']['g_1'][1], 678.9);",
             "assertEqual('hs1.method', hs1.method, 'POST');"
         };
         String mxml = getMXML(declarations, asserts);
diff --git a/compiler/src/test/java/mxml/tags/MXMLRemoteObjectTagTests.java b/compiler/src/test/java/mxml/tags/MXMLRemoteObjectTagTests.java
index 4cb616e..a4fe324 100644
--- a/compiler/src/test/java/mxml/tags/MXMLRemoteObjectTagTests.java
+++ b/compiler/src/test/java/mxml/tags/MXMLRemoteObjectTagTests.java
@@ -127,6 +127,13 @@
     		"            <d>456.7</d>",
     		"            <d>hello</d>",
     		"            <d>true</d>",
+    		"            <e>",
+    		"                <e_1>890.1</e_1>",
+            "            </e>",
+    		"            <f f_1='234.5'/>",
+    		"            <g g_1='howdy'>",
+    		"                <g_1>678.9</g_1>",
+            "            </g>",
     		"        </mx:arguments>",
     		"    </mx:method>",
     		"</mx:RemoteObject>"
@@ -140,7 +147,7 @@
             "assertEqual('ro1 is RemoteObject', ro1 is RemoteObject, true);",
             "assertEqual('ro1.operations.m1', ro1.operations['m1'] is Operation, true);",
             "assertEqual('ro1.operations.m1.name', ro1.operations['m1'].name, 'm1');",
-            "assertEqual('ro1.operations.m1.argumentNames.length', ro1.operations['m1'].argumentNames.length, 4);",
+            "assertEqual('ro1.operations.m1.argumentNames.length', ro1.operations['m1'].argumentNames.length, 7);",
             "assertEqual('ro1.operations.m1.argumentNames[0]', ro1.operations['m1'].argumentNames[0], 'a');",
             "assertEqual('ro1.operations.m1.argumentNames[1]', ro1.operations['m1'].argumentNames[1], 'b');",
             "assertEqual('ro1.operations.m1.argumentNames[1]', ro1.operations['m1'].argumentNames[2], 'c');",
@@ -151,6 +158,11 @@
             "assertEqual('ro1.operations.m1.arguments.d[0]', ro1.operations['m1'].arguments['d'][0], 456.7);",
             "assertEqual('ro1.operations.m1.arguments.d[1]', ro1.operations['m1'].arguments['d'][1], 'hello');",
             "assertEqual('ro1.operations.m1.arguments.d[2]', ro1.operations['m1'].arguments['d'][2], true);",
+            "assertEqual('ro1.operations.m1.arguments.e.e_1', ro1.operations['m1'].arguments['e']['e_1'], 890.1);",
+            "assertEqual('ro1.operations.m1.arguments.f.f_1', ro1.operations['m1'].arguments['f']['f_1'], 234.5);",
+            "assertEqual('ro1.operations.m1.arguments.g.g_1.length', ro1.operations['m1'].arguments['g']['g_1'].length, 2);",
+            "assertEqual('ro1.operations.m1.arguments.g.g_1[0]', ro1.operations['m1'].arguments['g']['g_1'][0], 'howdy');",
+            "assertEqual('ro1.operations.m1.arguments.g.g_1[1]', ro1.operations['m1'].arguments['g']['g_1'][1], 678.9);",
         };
         String mxml = getMXML(declarations, scriptDeclarations, asserts);
         compileAndRun(mxml, true, true, false, null);
diff --git a/compiler/src/test/java/mxml/tags/MXMLWebServiceTagTests.java b/compiler/src/test/java/mxml/tags/MXMLWebServiceTagTests.java
index 16ce452..6154f6e 100644
--- a/compiler/src/test/java/mxml/tags/MXMLWebServiceTagTests.java
+++ b/compiler/src/test/java/mxml/tags/MXMLWebServiceTagTests.java
@@ -149,6 +149,13 @@
     		"            <d>456.7</d>",
     		"            <d>hello</d>",
     		"            <d>true</d>",
+    		"            <e>",
+    		"                <e_1>890.1</e_1>",
+            "            </e>",
+    		"            <f f_1='234.5'/>",
+    		"            <g g_1='howdy'>",
+    		"                <g_1>678.9</g_1>",
+            "            </g>",
             "        </mx:arguments>",
             "    </mx:operation>",
     		"</mx:WebService>"
@@ -169,6 +176,11 @@
             "assertEqual('ws1.operations.op1.arguments.d[0]', ws1.operations['op1'].arguments['d'][0], 456.7);",
             "assertEqual('ws1.operations.op1.arguments.d[1]', ws1.operations['op1'].arguments['d'][1], 'hello');",
             "assertEqual('ws1.operations.op1.arguments.d[2]', ws1.operations['op1'].arguments['d'][2], true);",
+            "assertEqual('ws1.operations.op1.arguments.e.e_1', ws1.operations['op1'].arguments['e']['e_1'], 890.1);",
+            "assertEqual('ws1.operations.op1.arguments.f.f_1', ws1.operations['op1'].arguments['f']['f_1'], 234.5);",
+            "assertEqual('ws1.operations.op1.arguments.g.g_1.length', ws1.operations['op1'].arguments['g']['g_1'].length, 2);",
+            "assertEqual('ws1.operations.op1.arguments.g.g_1[0]', ws1.operations['op1'].arguments['g']['g_1'][0], 'howdy');",
+            "assertEqual('ws1.operations.op1.arguments.g.g_1[1]', ws1.operations['op1'].arguments['g']['g_1'][1], 678.9);",
             "assertEqual('ws1.operations.op1.request.a', ws1.operations['op1'].request['a'], 'abc');",
             "assertEqual('ws1.operations.op1.request.b', ws1.operations['op1'].request['b'], 123);",
             "assertEqual('ws1.operations.op1.request.c', ws1.operations['op1'].request['c'], false);",
@@ -176,6 +188,11 @@
             "assertEqual('ws1.operations.op1.request.d[0]', ws1.operations['op1'].request['d'][0], 456.7);",
             "assertEqual('ws1.operations.op1.request.d[1]', ws1.operations['op1'].request['d'][1], 'hello');",
             "assertEqual('ws1.operations.op1.request.d[2]', ws1.operations['op1'].request['d'][2], true);",
+            "assertEqual('ws1.operations.op1.request.e.e_1', ws1.operations['op1'].request['e']['e_1'], 890.1);",
+            "assertEqual('ws1.operations.op1.request.f.f_1', ws1.operations['op1'].request['f']['f_1'], 234.5);",
+            "assertEqual('ws1.operations.op1.request.g.g_1.length', ws1.operations['op1'].request['g']['g_1'].length, 2);",
+            "assertEqual('ws1.operations.op1.request.g.g_1[0]', ws1.operations['op1'].request['g']['g_1'][0], 'howdy');",
+            "assertEqual('ws1.operations.op1.request.g.g_1[1]', ws1.operations['op1'].request['g']['g_1'][1], 678.9);",
         };
         String mxml = getMXML(declarations, scriptDeclarations, asserts);
         compileAndRun(mxml, true, true, false, null);
@@ -195,6 +212,13 @@
     		"            <d>456.7</d>",
     		"            <d>hello</d>",
     		"            <d>true</d>",
+    		"            <e>",
+    		"                <e_1>890.1</e_1>",
+            "            </e>",
+    		"            <f f_1='234.5'/>",
+    		"            <g g_1='howdy'>",
+    		"                <g_1>678.9</g_1>",
+            "            </g>",
             "        </mx:request>",
             "    </mx:operation>",
     		"</mx:WebService>"
@@ -215,6 +239,11 @@
             "assertEqual('ws1.operations.op1.arguments.d[0]', ws1.operations['op1'].arguments['d'][0], 456.7);",
             "assertEqual('ws1.operations.op1.arguments.d[1]', ws1.operations['op1'].arguments['d'][1], 'hello');",
             "assertEqual('ws1.operations.op1.arguments.d[2]', ws1.operations['op1'].arguments['d'][2], true);",
+            "assertEqual('ws1.operations.op1.arguments.e.e_1', ws1.operations['op1'].arguments['e']['e_1'], 890.1);",
+            "assertEqual('ws1.operations.op1.arguments.f.f_1', ws1.operations['op1'].arguments['f']['f_1'], 234.5);",
+            "assertEqual('ws1.operations.op1.arguments.g.g_1.length', ws1.operations['op1'].arguments['g']['g_1'].length, 2);",
+            "assertEqual('ws1.operations.op1.arguments.g.g_1[0]', ws1.operations['op1'].arguments['g']['g_1'][0], 'howdy');",
+            "assertEqual('ws1.operations.op1.arguments.g.g_1[1]', ws1.operations['op1'].arguments['g']['g_1'][1], 678.9);",
             "assertEqual('ws1.operations.op1.request.a', ws1.operations['op1'].request['a'], 'abc');",
             "assertEqual('ws1.operations.op1.request.b', ws1.operations['op1'].request['b'], 123);",
             "assertEqual('ws1.operations.op1.request.c', ws1.operations['op1'].request['c'], false);",
@@ -222,6 +251,11 @@
             "assertEqual('ws1.operations.op1.request.d[0]', ws1.operations['op1'].request['d'][0], 456.7);",
             "assertEqual('ws1.operations.op1.request.d[1]', ws1.operations['op1'].request['d'][1], 'hello');",
             "assertEqual('ws1.operations.op1.request.d[2]', ws1.operations['op1'].request['d'][2], true);",
+            "assertEqual('ws1.operations.op1.request.e.e_1', ws1.operations['op1'].request['e']['e_1'], 890.1);",
+            "assertEqual('ws1.operations.op1.request.f.f_1', ws1.operations['op1'].request['f']['f_1'], 234.5);",
+            "assertEqual('ws1.operations.op1.request.g.g_1.length', ws1.operations['op1'].request['g']['g_1'].length, 2);",
+            "assertEqual('ws1.operations.op1.request.g.g_1[0]', ws1.operations['op1'].request['g']['g_1'][0], 'howdy');",
+            "assertEqual('ws1.operations.op1.request.g.g_1[1]', ws1.operations['op1'].request['g']['g_1'][1], 678.9);",
         };
         String mxml = getMXML(declarations, scriptDeclarations, asserts);
         compileAndRun(mxml, true, true, false, null);