                     continue;
                 
                 var propQName:XObjQName = new XObjQName(null, null, fieldName);
-                encodeValue(obj[fieldName], propQName, myElement, recurse, XObjMetadata.isPropByRef(classInfo, fieldName));
+                encodeValue(obj[fieldName], propQName, myElement, recurse, XObjMetadata.isPropByRef(classInfo, fieldName), false, fieldName);
             }
         }
         else if (typeType == XObjXMLEncoder.IXOBJ_COLLECTION
             || typeType == XObjXMLEncoder.ARRAY_TYPE)
         {
-            // link us into the heirarchy so that namespaces
-            // will be resolved up the chain correctly
-            parentNode.appendChild(myElement);
-            setAttributes(myElement, obj);
-            myElement.setName(XObjUtils.encodeElementTag(qname, myElement));
-            
-            // encode array elements
-            for (var j:int=0; j < obj.length; j++)
-            {
-                var localName:String = "item";  //assume item unless told otherwise
-                var member:* = obj[j];
+            var localName:String = "item";  //assume item unless told otherwise
+            
+            //if (encodeNullElements || obj.length > 0)
+            //{
+                // link us into the heirarchy so that namespaces
+                // will be resolved up the chain correctly
+                var flatten:Boolean;
                 
-                // force use of item for local name if simpleEncoderCompatible is true
-                if (!simpleEncoderCompatible)
+                if ((obj is IXObjCollection) && obj.length > 0)
                 {
-                    // look up the right qname to use
-                    if (obj is IXObjCollection)
-                    {
-                        localName = (obj as IXObjCollection).elementTagForMember(member);
-                    }
-                    else
-                    {
-                        // do we have meta?
-                        var meta:XObjMetadata = XObjMetadata.getMetadata(obj, false);
-                        if (meta && meta.arrayEntryTag)
-                            localName = meta.arrayEntryTag;
-                        else
-                            localName = tagForType(member);
-                    }
+                    var tag:String = (obj as IXObjCollection).elementTagForMember(obj[0]);
+                    // is the element tag same as propname?
+                    if (tag == propName)
+                        flatten = true;
+                }
+                    
+                if (flatten)
+                {
+                    // hoist children
+                    myElement = parentNode;
+                }
+                else
+                {
+                    parentNode.appendChild(myElement);
+                    setAttributes(myElement, obj);
+                    myElement.setName(XObjUtils.encodeElementTag(qname, myElement));
                 }
                 
-                qname = new XObjQName(null, null, localName);
-                
-                if (XObjUtils.isByReference(obj))
-                    encodeReference(member, qname, myElement);
-                else
-                    encodeValue(member, qname, myElement, recurse);
-            }
+                // encode array elements
+                for (var j:int=0; j < obj.length; j++)
+                {
+                    var member:* = obj[j];
+                    
+                    // force use of item for local name if simpleEncoderCompatible is true
+                    if (!simpleEncoderCompatible)
+                    {
+                        // look up the right qname to use
+                        if (obj is IXObjCollection)
+                        {
+                            localName = (obj as IXObjCollection).elementTagForMember(member);
+                        }
+                        else
+                        {
+                            // do we have meta?
+                            var meta:XObjMetadata = XObjMetadata.getMetadata(obj, false);
+                            if (meta && meta.arrayEntryTag)
+                                localName = meta.arrayEntryTag;
+                            else
+                                localName = tagForType(member);
+                        }
+                    }
+                    
+                    qname = new XObjQName(null, null, localName);
+                    
+                    if (XObjUtils.isByReference(obj))
+                        encodeReference(member, qname, myElement);
+                    else
+                        encodeValue(member, qname, myElement, recurse);
+                }
+            //}
         }
         else // must be simple type
         {

        return encodeValue(obj, q, parentNode, false, true);
    }
    
    internal function encodeValue(obj:Object, q:*, parentNode:XML, recurse:Boolean=true, referenceOnly:Boolean=false, isRoot:Boolean=false):XML
    {
        var qname:XObjQName;
        

        }
        else if (isRoot)
        {
            return internal_encodeValue(obj, qname, parentNode, true, referenceOnly, propName);
        }
        else if (referenceOnly)
        {
            return internal_encodeValue(obj, qname, parentNode, false, true, propName);
        }
        else if (recurse)
        {
