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 2019/03/01 07:28:39 UTC

[royale-asjs] 03/05: Cumulative WIP on AMFBinaryData refactor

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

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

commit 26ba471b541b560e279c0d23c53f7207f068458c
Author: greg-dove <gr...@gmail.com>
AuthorDate: Wed Feb 27 13:32:13 2019 +1300

    Cumulative WIP on AMFBinaryData refactor
---
 examples/amf/SampleAmfWebApp/README.txt            |   49 +
 examples/mxroyale/RemoteObjectAMFTest/README.txt   |   49 +
 examples/mxroyale/RemoteObjectAMFTest/pom.xml      |    2 +-
 .../RemoteObjectAMFTest/src/main/royale/App.mxml   |    8 +-
 frameworks/build.xml                               |   43 +-
 .../src/main/config/compile-js-config.xml          |   19 +-
 frameworks/projects/Collections/pom.xml            |   14 +
 .../src/main/config/compile-swf-config.xml         |   23 +-
 .../org/apache/royale/collections/ArrayList.as     |   25 +-
 .../projects/Core/src/main/royale/CoreClasses.as   |    2 +
 .../royale/org/apache/royale/utils/BinaryData.as   |  145 ++-
 .../org/apache/royale/utils/IBinaryDataInput.as    |   17 +-
 .../org/apache/royale/utils/IBinaryDataOutput.as   |   20 +-
 .../royale/flexUnitTests/BinaryDataTesterTest.as   |   22 +-
 .../main/royale/mx/collections/ArrayCollection.as  |   42 +-
 .../src/main/royale/mx/collections/ArrayList.as    |  212 ++--
 .../Network/src/main/royale/NetworkClasses.as      |   11 +-
 .../apache/royale/net/CompressedRemoteObject.as    |   10 +-
 .../royale/net/remoting/amf/AMFBinaryData.as       | 1299 --------------------
 .../royale/net/remoting/amf/AMFNetConnection.as    |   39 +-
 .../{IDataOutput.as => IDynamicPropertyOutput.as}  |   26 +-
 .../{IDataInput.as => IDynamicPropertyWriter.as}   |   23 +-
 pom.xml                                            |    4 +-
 23 files changed, 544 insertions(+), 1560 deletions(-)

diff --git a/examples/amf/SampleAmfWebApp/README.txt b/examples/amf/SampleAmfWebApp/README.txt
new file mode 100644
index 0000000..5c38129
--- /dev/null
+++ b/examples/amf/SampleAmfWebApp/README.txt
@@ -0,0 +1,49 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+DESCRIPTION
+
+See https://github.com/apache/royale-asjs/wiki/Apache-Royale-communication-with-AMF-and-RemoteObject
+for more information
+
+
+AMF is a great way to send data between an Apache Royale client and a backend server. The server could be written in Java, PHP, .NET, Ruby, Python and many other backend technologies.
+
+Read more about AMF here :https://en.wikipedia.org/wiki/Action_Message_Format
+
+Apache Royale supports AMF protocol and to demonstrate it we provide two projects:
+
+RemoteObjectAMFTest: (client implementation)
+Is the Apache Royale Client that uses RemoteObject to communicate with the backend server to send and receive data via AMF.Direct Link to this project
+
+SampleAmfWebApp: (server implementation)
+Is a Java WebApp that uses Apache Flex BlazeDS to expose some data and objects through an AMF endpoint. Direct Link to this project
+
+To run this example localy you can follow this steps. 
+Note: At this time some parts of the example only can be build with maven, we'll be providing at some time ANT build, but this is not priority. If you're interested in ANT build you can submit a PR)
+
+1. Build RemoteObjectAMFTest with maven using "mvn clean install". This generates the Apache Royale client.
+(currently in the examples/mxroyale folder)
+
+2. Build SampleAmfWebApp with maven using "mvn clean install". This generates the Java Web App with AMF support and will overlay the RemoteObjectAMFTest client compiled in the previous step
+(this project)
+
+3. Launch SampleAmfWebApp in the embedded Jetty web server with "java -jar target/SampleAmfWebApp-0.9.6-SNAPSHOT-exec.war". You should be in root SampleAmfWebApp folder. Notice: that SNAPSHOT number is just an example and can be different
+
+4. In a browser launch "http://localhost:8080" and try the examples.
diff --git a/examples/mxroyale/RemoteObjectAMFTest/README.txt b/examples/mxroyale/RemoteObjectAMFTest/README.txt
new file mode 100644
index 0000000..ce47e16
--- /dev/null
+++ b/examples/mxroyale/RemoteObjectAMFTest/README.txt
@@ -0,0 +1,49 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+DESCRIPTION
+
+See https://github.com/apache/royale-asjs/wiki/Apache-Royale-communication-with-AMF-and-RemoteObject
+for more information
+
+
+AMF is a great way to send data between an Apache Royale client and a backend server. The server could be written in Java, PHP, .NET, Ruby, Python and many other backend technologies.
+
+Read more about AMF here :https://en.wikipedia.org/wiki/Action_Message_Format
+
+Apache Royale supports AMF protocol and to demonstrate it we provide two projects:
+
+RemoteObjectAMFTest: (client implementation)
+Is the Apache Royale Client that uses RemoteObject to communicate with the backend server to send and receive data via AMF.Direct Link to this project
+
+SampleAmfWebApp: (server implementation)
+Is a Java WebApp that uses Apache Flex BlazeDS to expose some data and objects through an AMF endpoint. Direct Link to this project
+
+To run this example localy you can follow this steps.
+Note: At this time some parts of the example only can be build with maven, we'll be providing at some time ANT build, but this is not priority. If you're interested in ANT build you can submit a PR)
+
+1. Build RemoteObjectAMFTest with maven using "mvn clean install". This generates the Apache Royale client.
+(this project)
+
+2. Build SampleAmfWebApp with maven using "mvn clean install". This generates the Java Web App with AMF support and will overlay the RemoteObjectAMFTest client compiled in the previous step
+(currently in the examples/amf folder)
+
+3. Launch SampleAmfWebApp in the embedded Jetty web server with "java -jar target/SampleAmfWebApp-0.9.6-SNAPSHOT-exec.war". You should be in root SampleAmfWebApp folder. Notice: that SNAPSHOT number is just an example and can be different
+
+4. In a browser launch "http://localhost:8080" and try the examples.
diff --git a/examples/mxroyale/RemoteObjectAMFTest/pom.xml b/examples/mxroyale/RemoteObjectAMFTest/pom.xml
index dd70a33..673202e 100644
--- a/examples/mxroyale/RemoteObjectAMFTest/pom.xml
+++ b/examples/mxroyale/RemoteObjectAMFTest/pom.xml
@@ -72,7 +72,7 @@
       <type>swc</type>
       <scope>provided</scope>
     </dependency>
-      
+
     <dependency>
       <groupId>org.apache.royale.framework</groupId>
       <artifactId>Network</artifactId>
diff --git a/examples/mxroyale/RemoteObjectAMFTest/src/main/royale/App.mxml b/examples/mxroyale/RemoteObjectAMFTest/src/main/royale/App.mxml
index df69a25..7fa241a 100644
--- a/examples/mxroyale/RemoteObjectAMFTest/src/main/royale/App.mxml
+++ b/examples/mxroyale/RemoteObjectAMFTest/src/main/royale/App.mxml
@@ -32,11 +32,12 @@ limitations under the License.
             import mx.rpc.events.FaultEvent;
             import mx.rpc.events.ResultEvent;
             import mx.rpc.remoting.Operation;
+            import mx.collections.ArrayCollection;
 
             import org.apache.royale.collections.ArrayList;
             import org.apache.royale.events.Event;
-            import org.apache.royale.net.remoting.amf.AMFBinaryData;
             import org.apache.royale.reflection.registerClassAlias;
+            import org.apache.royale.reflection.getAliasByClass;
 
             import valueObjects.ClientValueObject;
             import valueObjects.Product;
@@ -45,8 +46,9 @@ limitations under the License.
 
 
             private function iniApp(event:Event):void{
-                AMFBinaryData.DEBUG = true;
-                registerClassAlias('org.apache.royale.collections.ArrayList', ArrayList);
+                //swap in ArrayCollection for ArrayList
+                registerClassAlias(getAliasByClass(ArrayCollection), ArrayList);
+
                 // Test CompressedRemoteObject
                 // trace("init CompressedRemoteObject.includePackages");
                 // CompressedRemoteObject.includePackages = ["valueObjects."];
diff --git a/frameworks/build.xml b/frameworks/build.xml
index 43c6aa3..7538236 100644
--- a/frameworks/build.xml
+++ b/frameworks/build.xml
@@ -21,7 +21,7 @@
 <!-- Note:
     If you modify this file you may have to make the same change in build_framework.xml.
     build_framework.xml is renamed to build.xml when it is packaged.
-    It is used to build the frameworks directory from the zip file. 
+    It is used to build the frameworks directory from the zip file.
 -->
 <project name="frameworks" default="main" basedir=".">
 
@@ -45,21 +45,21 @@
     </condition>
     <condition property="isWindows">
         <os family="windows" />
-    </condition>   
+    </condition>
     <condition property="isLinux">
         <and>
-          <os family="unix"/>    
+          <os family="unix"/>
           <not>
-            <os family="mac"/>    
+            <os family="mac"/>
           </not>
         </and>
-    </condition>  
+    </condition>
 
     <property file="${ROYALE_HOME}/env.properties"/>
     <property environment="env"/>
     <property file="${ROYALE_HOME}/build.properties"/>
     <property name="ROYALE_HOME" value="${ROYALE_HOME}" />
- 
+
     <target name="main" depends="check-compile-env,clean,prepare,compile,fonts"
         description="Clean build of all SWCs"/>
 
@@ -105,7 +105,7 @@
     <target name="thirdparty-downloads" unless="no.thirdparty-downloads" description="Downloads all the required thirdparty code.">
         <ant antfile="${basedir}/downloads.xml" dir="${basedir}"/>
     </target>
-    
+
     <target name="compile" description="Builds all SWCs but not their resource bundles">
         <!-- order may matter due to dependencies -->
         <antcall target="Language"/>
@@ -113,6 +113,8 @@
         <antcall target="Core"/>
         <antcall target="Graphics"/>
         <antcall target="Binding"/>
+        <antcall target="Reflection"/>
+        <antcall target="Network"/>
         <antcall target="Collections"/>
         <antcall target="Basic"/>
 	<antcall target="Ace"/>
@@ -128,8 +130,7 @@
         <antcall target="HTML5"/>
         <antcall target="JQuery"/>
         <antcall target="Mobile"/>
-        <antcall target="Reflection"/>
-        <antcall target="Network"/>
+
         <antcall target="Storage"/>
         <antcall target="XML"/>
         <antcall target="Text"/>
@@ -144,29 +145,29 @@
         <antcall target="JewelTheme"/>
 		<antcall target="Icons"/>
     </target>
-    
+
     <target name="fonts">
         <ant dir="${basedir}/fontsrc" target="main"/>
     </target>
-    
+
     <target name="other.locales" description ="Builds resource SWCs for all locales">
         <!--<ant dir="${basedir}/projects/RoyaleUI" target="other.locales"/>-->
     </target>
-    
+
     <target name="doc" >
         <ant dir="${basedir}/projects/Core" target="doc" />
     </target>
-   
+
     <!--
 		Cleanup
 	-->
 
     <target name="super-clean" depends="thirdparty-clean,clean" description="Cleans everything including thirdparty downloads."/>
-	
+
     <target name="thirdparty-clean" unless="no.thirdparty-clean" description="Removes all thirdparty downloads.">
         <ant antfile="${basedir}/downloads.xml" target="clean" dir="${basedir}"/>
     </target>
-    
+
     <target name="clean" description="Cleans all SWCs and their resource bundles">
         <!-- Delete output from SWC projects -->
         <ant dir="${basedir}/projects/Testing" target="clean"/>
@@ -209,7 +210,7 @@
             <fileset dir="${basedir}/projects">
                 <include name="*/bin/**"/>
             </fileset>
-        </delete> 
+        </delete>
         <!-- Delete empty folders -->
         <delete dir="${basedir}/libs" failonerror="false">
             <include name="*.swc"/>
@@ -228,7 +229,7 @@
             <exclude name="js-index-template.html" />
         </delete>
     </target>
-    
+
     <target name="Testing" description="Clean build of Testing.swc">
         <ant dir="${basedir}/projects/Testing"/>
     </target>
@@ -236,7 +237,7 @@
     <target name="Binding" description="Clean build of Binding.swc">
         <ant dir="${basedir}/projects/Binding"/>
     </target>
-    
+
     <target name="Charts" description="Clean build of Charts.swc">
         <ant dir="${basedir}/projects/Charts"/>
     </target>
@@ -276,7 +277,7 @@
     <target name="FontAwesome" description="Clean build of FontAwesome.swc">
         <ant dir="${basedir}/projects/FontAwesome"/>
     </target>
-    
+
     <target name="Formatters" description="Clean build of Formatters.swc">
         <ant dir="${basedir}/projects/Formatters"/>
     </target>
@@ -316,7 +317,7 @@
 	<target name="MaterialDesignLite" description="Clean build of MaterialDesignLite.swc">
         <ant dir="${basedir}/projects/MaterialDesignLite"/>
     </target>
-	
+
     <target name="Mobile" description="Clean build of Mobile.swc">
         <ant dir="${basedir}/projects/Mobile"/>
     </target>
@@ -380,7 +381,7 @@
             token="&lt;target&gt;SWF&lt;/target&gt;"
             value="" />
     </target>
-    
+
 	<target name="playerglobal-setswfversion" description="Set the swfversion to insert into the -config file">
 		<condition property="playerglobal.swfversion" value="11">
 			<equals arg1="${playerglobal.version}" arg2="10.2" />
diff --git a/frameworks/js/projects/CollectionsJS/src/main/config/compile-js-config.xml b/frameworks/js/projects/CollectionsJS/src/main/config/compile-js-config.xml
index febcce3..7ffafa3 100644
--- a/frameworks/js/projects/CollectionsJS/src/main/config/compile-js-config.xml
+++ b/frameworks/js/projects/CollectionsJS/src/main/config/compile-js-config.xml
@@ -20,7 +20,7 @@
 
     <compiler>
         <accessible>false</accessible>
-        
+
         <!-- build both SWF and JS. -->
         <targets>
             <target>SWF</target>
@@ -51,9 +51,9 @@
           <name>NonCommittingChangeEvent</name>
           <name>Transient</name>
         </keep-as3-metadata>
-	  
+
         <locale/>
-        
+
         <!-- overwrite the default library-path setting -->
         <library-path>
             <path-element>../../../../../../../js/libs/GCL.swc</path-element>
@@ -61,29 +61,30 @@
              if these swcs are on the external-library-path then their requires
              will not be listed -->
             <path-element>../../../../../libs/CoreJS.swc</path-element>
+            <path-element>../../../../../libs/NetworkJS.swc</path-element>
         </library-path>
-        
+
         <namespaces>
             <namespace>
                 <uri>library://ns.apache.org/royale/basic</uri>
                 <manifest>../../../../../../projects/Collections/src/main/resources/basic-manifest.xml</manifest>
             </namespace>
         </namespaces>
-        
+
         <source-path>
             <path-element>../../../../../../projects/Collections/src/main/royale</path-element>
         </source-path>
-        
+
         <warn-no-constructor>false</warn-no-constructor>
     </compiler>
-    
+
     <include-classes>
         <class>CollectionsClasses</class>
     </include-classes>
-    
+
     <include-namespaces>
         <uri>library://ns.apache.org/royale/basic</uri>
     </include-namespaces>
-        
+
 
 </royale-config>
diff --git a/frameworks/projects/Collections/pom.xml b/frameworks/projects/Collections/pom.xml
index e55d7f9..c949d39 100644
--- a/frameworks/projects/Collections/pom.xml
+++ b/frameworks/projects/Collections/pom.xml
@@ -72,6 +72,20 @@
       <type>swc</type>
       <classifier>js</classifier>
     </dependency>
+    <dependency>
+      <groupId>org.apache.royale.framework</groupId>
+      <artifactId>Network</artifactId>
+      <version>0.9.6-SNAPSHOT</version>
+      <type>swc</type>
+      <classifier>swf</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.royale.framework</groupId>
+      <artifactId>Network</artifactId>
+      <version>0.9.6-SNAPSHOT</version>
+      <type>swc</type>
+      <classifier>js</classifier>
+    </dependency>
   </dependencies>
 
 </project>
diff --git a/frameworks/projects/Collections/src/main/config/compile-swf-config.xml b/frameworks/projects/Collections/src/main/config/compile-swf-config.xml
index f1896f7..c702beb 100644
--- a/frameworks/projects/Collections/src/main/config/compile-swf-config.xml
+++ b/frameworks/projects/Collections/src/main/config/compile-swf-config.xml
@@ -20,7 +20,7 @@
 
     <compiler>
         <accessible>false</accessible>
-        
+
         <!-- build both SWF and JS. -->
         <targets>
             <target>SWF</target>
@@ -31,15 +31,16 @@
         <external-library-path>
             <path-element>${env.AIR_HOME}/frameworks/libs/air/airglobal.swc</path-element>
             <path-element>../../../../../libs/Core.swc</path-element>
+            <path-element>../../../../../libs/Network.swc</path-element>
         </external-library-path>
-        
+
 		<mxml>
 			<children-as-data>true</children-as-data>
 		</mxml>
 		<binding-value-change-event>org.apache.royale.events.ValueChangeEvent</binding-value-change-event>
 		<binding-value-change-event-kind>org.apache.royale.events.ValueChangeEvent</binding-value-change-event-kind>
 		<binding-value-change-event-type>valueChange</binding-value-change-event-type>
-        
+
         <define>
             <name>COMPILE::SWF</name>
             <value>true</value>
@@ -56,9 +57,9 @@
           <name>NonCommittingChangeEvent</name>
           <name>Transient</name>
         </keep-as3-metadata>
-	  
+
         <locale/>
-        
+
         <library-path/>
 
         <namespaces>
@@ -67,23 +68,23 @@
                 <manifest>../resources/basic-manifest.xml</manifest>
             </namespace>
         </namespaces>
-        
+
         <source-path>
             <path-element>../royale</path-element>
         </source-path>
-        
+
         <warn-no-constructor>false</warn-no-constructor>
     </compiler>
-    
+
     <include-classes>
         <class>CollectionsClasses</class>
     </include-classes>
-    
+
     <include-namespaces>
         <uri>library://ns.apache.org/royale/basic</uri>
     </include-namespaces>
-        
+
     <target-player>${playerglobal.version}</target-player>
-	
+
 
 </royale-config>
diff --git a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ArrayList.as b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ArrayList.as
index 8fc316a..0281628 100644
--- a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ArrayList.as
+++ b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ArrayList.as
@@ -24,6 +24,10 @@ package org.apache.royale.collections
 	import org.apache.royale.events.EventDispatcher;
 	import org.apache.royale.events.IEventDispatcher;
     import org.apache.royale.events.CollectionEvent;
+	
+	import org.apache.royale.net.utils.IExternalizable;
+	import org.apache.royale.net.utils.IDataInput;
+	import org.apache.royale.net.utils.IDataOutput;
 
     //--------------------------------------
     //  Events
@@ -90,7 +94,7 @@ package org.apache.royale.collections
      *  @playerversion AIR 2.6
      *  @productversion Royale 0.0
      */
-	public class ArrayList extends EventDispatcher implements IBead, ICollectionView, IArrayList
+	public class ArrayList extends EventDispatcher implements IBead, ICollectionView, IArrayList, IExternalizable
 	{
         /**
          *  Constructor.
@@ -423,6 +427,25 @@ package org.apache.royale.collections
         {
             return _source ? _source.length : 0;
         }
+		
+		
+		/**
+		 *  @private
+		 *  Ensures that only the source property is serialized.
+		 */
+		public function readExternal(input:IDataInput):void
+		{
+			source = input.readObject() as Array;
+		}
+		
+		/**
+		 *  @private
+		 *  Ensures that only the source property is serialized.
+		 */
+		public function writeExternal(output:IDataOutput):void
+		{
+			output.writeObject(source);
+		}
 
 	}
 }
diff --git a/frameworks/projects/Core/src/main/royale/CoreClasses.as b/frameworks/projects/Core/src/main/royale/CoreClasses.as
index 3809370..c73dae3 100644
--- a/frameworks/projects/Core/src/main/royale/CoreClasses.as
+++ b/frameworks/projects/Core/src/main/royale/CoreClasses.as
@@ -188,6 +188,8 @@ import org.apache.royale.events.ItemRemovedEvent; ItemRemovedEvent;
     import org.apache.royale.geom.Rectangle; Rectangle;
     import org.apache.royale.utils.AnimationUtil; AnimationUtil;
     import org.apache.royale.utils.BinaryData; BinaryData;
+	import org.apache.royale.utils.IBinaryDataInput; IBinaryDataInput;
+	import org.apache.royale.utils.IBinaryDataOutput; IBinaryDataOutput;
 	import org.apache.royale.utils.BrowserInfo; BrowserInfo;
 	COMPILE::SWF
 	{
diff --git a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/BinaryData.as b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/BinaryData.as
index c2e3856..ec853b9 100644
--- a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/BinaryData.as
+++ b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/BinaryData.as
@@ -64,7 +64,7 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
     {
         if(goog.DEBUG)
         {
-            if(bytes && typeof bytes.byteLength != "number")
+            if(bytes && typeof bytes.byteLength != "number" && bytes.buffer !== undefined)
                 throw new TypeError("BinaryData can only be initialized with ArrayBuffer");
         }
         ba = bytes ? bytes as ArrayBuffer : new ArrayBuffer(0);
@@ -179,13 +179,13 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
     }
 
     COMPILE::SWF
-    private var ba:ByteArray;
+	protected var ba:ByteArray;
 
     COMPILE::JS
-    private var ba:ArrayBuffer;
+	protected var ba:ArrayBuffer;
 
     COMPILE::JS
-    private var _position:int = 0;
+    protected var _position:int = 0;
 
     /**
      * Get the platform-specific data for sending.
@@ -279,28 +279,52 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
      *  @playerversion Flash 10.2
      *  @playerversion AIR 2.6
      *  @productversion Royale 0.0
+     *
+     *  @royaleignorecoercion ArrayBuffer
      */
-    public function writeBytes(source:BinaryData, offset:uint = 0, length:uint = 0):void
+    public function writeBinaryData(bytes:BinaryData, offset:uint = 0, length:uint = 0):void
     {
+		if (!bytes) throw new TypeError('Error #2007: Parameter bytes must be non-null.');
+		if (bytes == this) throw new Error('Parameter bytes must be another instance.');
         COMPILE::SWF
         {
-            ba.writeBytes(source.ba,offset,length);
+            ba.writeBytes(bytes.ba,offset,length);
         }
 
         COMPILE::JS
         {
-
-            if (length == 0) length = source.length - offset ;
-            if (_position + length > _len) {
-                setBufferSize(_position + length);
-            }
-            var dest:Uint8Array = new Uint8Array(ba, _position, length);
-            var src:Uint8Array = new Uint8Array(source.ba, offset,length);
-            dest.set(src);
-            _position += length;
+			writeBytes(bytes.ba as ArrayBuffer)
         }
 
     }
+    
+	COMPILE::SWF
+	public function writeBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void {
+		ba.writeBytes(bytes, offset, length);
+	}
+ 
+	COMPILE::JS
+	public function writeBytes(bytes:ArrayBuffer, offset:uint = 0, length:uint = 0):void {
+		
+		if (!bytes) throw new TypeError('Error #2007: Parameter bytes must be non-null.')
+		if (offset > bytes.byteLength) {
+			//offset exceeds source length
+			throw new RangeError('Error #2006: The supplied index is out of bounds.');
+		}
+		if (length == 0) length = bytes.byteLength - offset ;
+		else if (length > bytes.byteLength - offset) {
+			//length exceeds source length
+			throw new RangeError('Error #2006: The supplied index is out of bounds.');
+		}
+		
+		if (_position + length > _len) {
+			setBufferSize(_position + length);
+		}
+		var dest:Uint8Array = new Uint8Array(ba, _position, length);
+		var src:Uint8Array = new Uint8Array(bytes, offset, length);
+		dest.set(src);
+		_position += length;
+	}
 
     /**
      *  Write a short integer (16 bits, typically represented by a 32 bit int parameter between -32768 and 65535)
@@ -392,7 +416,6 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
                 arr[_position++] = (val & 0x00ff0000) >> 16;
                 arr[_position++] = (val & 0xff000000) >> 24;
             }
-
         }
     }
 
@@ -465,7 +488,7 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
         }
         COMPILE::JS
         {
-            return !!getTypedArray()[_position++];// Boolean(readUnsignedByte());
+            return Boolean(getTypedArray()[_position++]);
         }
     }
 
@@ -518,7 +541,7 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
      *  If length is omitted or is zero, all bytes are read following the current position to the end
      *  of this BinaryData. If offset is also omitted, it defaults to zero.
      *
-     *  @param {BinaryData} destination The destination BinaryData to write bytes into from the current position
+     *  @param {BinaryData} bytes The destination BinaryData to write bytes into from the current position
      *  @param {uint} offset The optional offset value of the starting bytes to write inside destination
      *  @param {uint} length The optional length value of the bytes to read
      *
@@ -527,31 +550,44 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
      *  @playerversion AIR 2.6
      *  @productversion Royale 0.0
      */
-    public function readBytes(destination:BinaryData, offset:uint = 0, length:uint = 0):void
+    public function readBinaryData(bytes:BinaryData, offset:uint = 0, length:uint = 0):void
     {
+		if (!bytes) throw new TypeError('Error #2007: Parameter bytes must be non-null.');
+        if (bytes == this) throw new Error('Parameter bytes must be another instance.');
         COMPILE::SWF
         {
-            ba.readBytes(destination.ba,offset,length);
+            ba.readBytes(bytes.ba,offset,length);
         }
 
         COMPILE::JS
         {
-            //do we need to check offset and length and sanitize or throw an error?
-
-            if (length == 0) length = _len - _position ;
-            //extend the destination length if necessary
-            var extra:int = offset + length - destination._len;
-            if (extra > 0)
-                destination.growBuffer(extra);
-            var src:Uint8Array = new Uint8Array(ba, _position,length);
-            var dest:Uint8Array = new Uint8Array(destination.ba, offset, length);
-
-            dest.set(src);
-            //todo: check position behavior vs. flash implementation (do either or both advance their internal position) :
-            _position+=length;
+			if (length == 0) length = _len - _position ;
+            bytes.mergeInToArrayBuffer(offset,new Uint8Array(ba, _position, length));
+			_position+=length;
         }
-
     }
+    
+    COMPILE::SWF
+    public function readBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void {
+        ba.readBytes(bytes, offset, length);
+    }
+    
+	
+	COMPILE::JS
+    public function readBytes(bytes:ArrayBuffer, offset:uint = 0, length:uint = 0):void {
+		if (!bytes) throw new TypeError('Error #2007: Parameter bytes must be non-null.');
+        if(bytes == ba) throw new Error('cannot read into internal ArrayBuffer as both destination and source');
+		if (length == 0) length = _len - _position ;
+		//extend the destination length if necessary
+		var extra:int = offset + length - bytes.byteLength;
+        if (extra > 0)  throw new Error('cannot read into destination ArrayBuffer, insufficient fixed length');
+		var src:Uint8Array = new Uint8Array(ba, _position, length);
+		var dest:Uint8Array = new Uint8Array(bytes, offset, length);
+		
+		dest.set(src);
+		_position+=length;
+    }
+	
 
     /**
      *  Read a byte of binary data at the specified index. Does not change the <code>position</code> property.
@@ -577,10 +613,10 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
     }
 
     COMPILE::JS
-    private var _typedArray:Uint8Array;
+	protected var _typedArray:Uint8Array;
 
     COMPILE::JS
-    private function getTypedArray():Uint8Array
+    protected function getTypedArray():Uint8Array
     {
         if(_typedArray == null)
             _typedArray = new Uint8Array(ba);
@@ -588,10 +624,10 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
     }
 
     COMPILE::JS
-    private var _dataView:DataView;
+	protected var _dataView:DataView;
 
     COMPILE::JS
-    private function getDataView():DataView
+	protected function getDataView():DataView
     {
         if(!_dataView)
             _dataView = new DataView(ba);
@@ -767,7 +803,7 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
     }
 
     COMPILE::JS
-    private var _len:uint;
+    protected var _len:uint;
 
     /**
      *  The length of this BinaryData, in bytes.
@@ -945,7 +981,7 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
      *  from the BinaryData and returns a string.
      *  The <code>position</code> is advanced to the first byte following the string's bytes.
      *
-     *  @param {uint} length An unsigned short indicating the length of the UTF-8 bytes.
+     *  @param {uint} length An unsigned integer indicating the length of the UTF-8 bytes.
      *
      *  @langversion 3.0
      *  @playerversion Flash 10.2
@@ -963,6 +999,9 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
         {
             // Code taken from GC
             // Use native implementations if/when available
+            if (_position + length > _len) {
+                throw new Error('Error #2030: End of file was encountered.');
+            }
             var bytes:Uint8Array = new Uint8Array(ba,_position,length);
             if('TextDecoder' in window)
             {
@@ -1069,13 +1108,18 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
     }
 
     COMPILE::JS
-    private function mergeInToArrayBuffer(offset:uint, newBytes:Uint8Array):uint {
+    protected function mergeInToArrayBuffer(offset:uint, newBytes:Uint8Array):uint {
         var newContentLength:uint = newBytes.length;
         var dest:Uint8Array;
-		var mergeUpperBound:uint = offset + newContentLength
+		var mergeUpperBound:uint = offset + newContentLength;
         if (mergeUpperBound > _len) {
-            dest = new Uint8Array(offset + newContentLength);
-            dest.set(new Uint8Array(ba, 0, offset));
+            dest = new Uint8Array(mergeUpperBound);
+            if (_len) {
+                var copyOffset:uint = Math.min(offset, _len);
+				if (copyOffset > 0){
+					dest.set(new Uint8Array(ba, 0, copyOffset));
+				}
+            }
             dest.set(newBytes, offset);
             ba = dest.buffer;
             _typedArray = dest;
@@ -1089,7 +1133,7 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
     }
 
     COMPILE::JS
-    private function getUTFBytes(str:String, prependLength:Boolean):Uint8Array {
+    protected function getUTFBytes(str:String, prependLength:Boolean):Uint8Array {
         // Code taken from GC
         // Use native implementations if/when available
         var bytes:Uint8Array;
@@ -1151,6 +1195,17 @@ public class BinaryData implements IBinaryDataInput, IBinaryDataOutput
         }
         return bytes;
     }
+    
+    //required for interface compatibility on swf
+    COMPILE::SWF
+    public function readMultiByte(length:uint, charSet:String):String {
+        return ba.readMultiByte(length, charSet);
+    }
+	
+	COMPILE::SWF
+	public function writeMultiByte(value:String, charSet:String):void{
+		ba.writeMultiByte(value, charSet);
+	}
 
 }
 }
diff --git a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/IBinaryDataInput.as b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/IBinaryDataInput.as
index a2a6bc0..c430ed7 100644
--- a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/IBinaryDataInput.as
+++ b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/IBinaryDataInput.as
@@ -17,10 +17,21 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 package org.apache.royale.utils {
+COMPILE::SWF{
+    import flash.utils.ByteArray
+}
 public interface IBinaryDataInput {
 
-    function readBytes(bytes:BinaryData, offset:uint = 0, length:uint = 0):void;
+    function readBinaryData(bytes:BinaryData, offset:uint = 0, length:uint = 0):void;
 
+    COMPILE::SWF{
+		function readBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void;
+    }
+	
+	COMPILE::JS{
+		function readBytes(bytes:ArrayBuffer, offset:uint = 0, length:uint = 0):void;
+	}
+    
     function readBoolean():Boolean;
     function readByte():int;
     function readUnsignedByte():uint;
@@ -37,10 +48,6 @@ public interface IBinaryDataInput {
 
     function get bytesAvailable():uint;
 
-    // function readObject():*;
-    // function get objectEncoding():uint;
-    // function set objectEncoding(version:uint):void;
-
     function get endian():String;
     function set endian(type:String):void;
 }
diff --git a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/IBinaryDataOutput.as b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/IBinaryDataOutput.as
index 14f7b3a..92f92b6 100644
--- a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/IBinaryDataOutput.as
+++ b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/IBinaryDataOutput.as
@@ -17,8 +17,20 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 package org.apache.royale.utils {
+COMPILE::SWF{
+    import flash.utils.ByteArray
+}
 public interface IBinaryDataOutput {
-    function writeBytes(bytes:BinaryData,offset:uint = 0,length:uint = 0):void;
+    
+    function writeBinaryData(bytes:BinaryData,offset:uint = 0,length:uint = 0):void;
+	
+	COMPILE::SWF{
+		function writeBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void;
+	}
+	
+	COMPILE::JS{
+		function writeBytes(bytes:ArrayBuffer, offset:uint = 0, length:uint = 0):void;
+	}
 
     function writeBoolean(value:Boolean):void;
     function writeByte(value:int):void;
@@ -31,11 +43,7 @@ public interface IBinaryDataOutput {
   //  function writeMultiByte(value:String,charSet:String):void;
     function writeUTF(value:String):void;
     function writeUTFBytes(value:String):void;
-
-    // function writeObject(object:*):void;
-    // function get objectEncoding():uint;
-    // function set objectEncoding(version:uint):void;
-
+    
     function get endian():String;
     function set endian(type:String):void;
 }
diff --git a/frameworks/projects/Core/src/test/royale/flexUnitTests/BinaryDataTesterTest.as b/frameworks/projects/Core/src/test/royale/flexUnitTests/BinaryDataTesterTest.as
index f27c4ff..22068a8 100644
--- a/frameworks/projects/Core/src/test/royale/flexUnitTests/BinaryDataTesterTest.as
+++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/BinaryDataTesterTest.as
@@ -522,20 +522,20 @@ package flexUnitTests {
 
 
     [Test]
-    public function testWriteBytes():void
+    public function testWriteBinaryData():void
     {
         var ba:BinaryData = new BinaryData();
         for (var i:int=0;i<50;i++) ba.writeByte(i);
 
 
         var newBa:BinaryData = new BinaryData();
-        newBa.writeBytes(ba);
+        newBa.writeBinaryData(ba);
 
-        assertEquals(50, newBa.length, "BinaryData writeBytes: length");
-        assertEquals(50, newBa.position, "BinaryData writeBytes: position");
+        assertEquals(50, newBa.length, "BinaryData writeBinaryData: length");
+        assertEquals(50, newBa.position, "BinaryData writeBinaryData: position");
 
         for (i=0;i<50;i++) {
-            assertEquals(i, newBa.array[i], "BinaryData writeBytes: content check");
+            assertEquals(i, newBa.array[i], "BinaryData writeBinaryData: content check");
         }
 
 
@@ -543,20 +543,20 @@ package flexUnitTests {
     }
 
     [Test]
-    public function testReadBytes():void
+    public function testReadBinaryData():void
     {
         var ba:BinaryData = new BinaryData();
         for (var i:int=0;i<50;i++) ba.writeByte(i);
         ba.position=0;
         var newBa:BinaryData = new BinaryData();
 
-        ba.readBytes(newBa,5,10);
-        assertEquals(10, ba.position, "BinaryData readBytes: position");
-        assertEquals(15, newBa.length, "BinaryData readBytes: length");
-        assertEquals(0, newBa.position, "BinaryData readBytes: position");
+        ba.readBinaryData(newBa,5,10);
+        assertEquals(10, ba.position, "BinaryData readBinaryData: position");
+        assertEquals(15, newBa.length, "BinaryData readBinaryData: length");
+        assertEquals(0, newBa.position, "BinaryData readBinaryData: position");
         var expected:Array = [0,0,0,0,0,0,1,2,3,4,5,6,7,8,9];
         for (i=5;i<15;i++) {
-            assertEquals(expected[i], newBa.array[i], "BinaryData readBytes: content check");
+            assertEquals(expected[i], newBa.array[i], "BinaryData readBinaryData: content check");
         }
     }
 
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayCollection.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayCollection.as
index 1b9e543..1dc975e 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayCollection.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayCollection.as
@@ -29,6 +29,12 @@ import mx.core.mx_internal;
 
 use namespace mx_internal;
 */
+
+import org.apache.royale.net.utils.IExternalizable;
+import org.apache.royale.net.utils.IDataInput;
+import org.apache.royale.net.utils.IDataOutput;
+
+
 [DefaultProperty("source")]
 
 [RemoteClass(alias="flex.messaging.io.ArrayCollection")]
@@ -40,7 +46,7 @@ use namespace mx_internal;
  *  interfaces. Operations on a ArrayCollection instance modify the data source;
  *  for example, if you use the <code>removeItemAt()</code> method on an
  *  ArrayCollection, you remove the item from the underlying Array.
- * 
+ *
  *  @mxml
  *
  *  <p>The <code>&lt;mx:ArrayCollection&gt;</code> tag inherits all the attributes of its
@@ -66,13 +72,13 @@ use namespace mx_internal;
  *  if (firstItem == firstItemFromCursor)
  *        doCelebration();
  *  </pre>
- *  
+ *
  *  @langversion 3.0
  *  @playerversion Flash 9
  *  @playerversion AIR 1.1
  *  @productversion Flex 3
  */
-public class ArrayCollection extends ListCollectionView //implements IExternalizable
+public class ArrayCollection extends ListCollectionView implements IExternalizable
 {
     //include "../core/Version.as";
 
@@ -89,7 +95,7 @@ public class ArrayCollection extends ListCollectionView //implements IExternaliz
      *  If no array is specified an empty array will be used.</p>
      *
      *  @param source The source Array.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -120,7 +126,7 @@ public class ArrayCollection extends ListCollectionView //implements IExternaliz
      *  The ArrayCollection object does not represent any changes that you make
      *  directly to the source array. Always use
      *  the ICollectionView or IList methods to modify the collection.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -142,6 +148,32 @@ public class ArrayCollection extends ListCollectionView //implements IExternaliz
     {
         list = new ArrayList(s);
     }
+	
+	
+	
+	/**
+	 *  @private
+	 *  Ensures that only the source property is serialized.
+	 */
+	public function readExternal(input:IDataInput):void
+	{
+		if (list is IExternalizable)
+			IExternalizable(list).readExternal(input);
+		else
+			source = input.readObject() as Array;
+	}
+	
+	/**
+	 *  @private
+	 *  Ensures that only the source property is serialized.
+	 */
+	public function writeExternal(output:IDataOutput):void
+	{
+		if (list is IExternalizable)
+			IExternalizable(list).writeExternal(output);
+		else
+			output.writeObject(source);
+	}
 
 }
 
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayList.as b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayList.as
index 1c0a614..763f54b 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayList.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayList.as
@@ -17,7 +17,7 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 
-package mx.collections 
+package mx.collections
 {
 import mx.events.CollectionEvent;
 import mx.events.CollectionEventKind;
@@ -38,15 +38,19 @@ import mx.utils.UIDUtil;
 import org.apache.royale.utils.UIDUtil;
 import org.apache.royale.reflection.getQualifiedClassName;
 
+import org.apache.royale.net.utils.IExternalizable;
+import org.apache.royale.net.utils.IDataInput;
+import org.apache.royale.net.utils.IDataOutput;
+
 //--------------------------------------
 //  Events
 //--------------------------------------
 
 /**
  *  Dispatched when the IList has been updated in some way.
- *  
+ *
  *  @eventType mx.events.CollectionEvent.COLLECTION_CHANGE
- *  
+ *
  *  @langversion 3.0
  *  @playerversion Flash 9
  *  @playerversion AIR 1.1
@@ -65,26 +69,26 @@ import org.apache.royale.reflection.getQualifiedClassName;
 [DefaultProperty("source")]
 
 /**
- *  The ArrayList class is a simple implementation of IList 
- *  that uses a backing Array as the source of the data. 
- * 
- *  Items in the backing Array can be accessed and manipulated 
+ *  The ArrayList class is a simple implementation of IList
+ *  that uses a backing Array as the source of the data.
+ *
+ *  Items in the backing Array can be accessed and manipulated
  *  using the methods and properties of the <code>IList</code>
- *  interface. Operations on an ArrayList instance modify the 
- *  data source; for example, if you use the <code>removeItemAt()</code> 
- *  method on an ArrayList, you remove the item from the underlying 
+ *  interface. Operations on an ArrayList instance modify the
+ *  data source; for example, if you use the <code>removeItemAt()</code>
+ *  method on an ArrayList, you remove the item from the underlying
  *  Array.
- * 
+ *
  *  This base class will not throw ItemPendingErrors but it
  *  is possible that a subclass might.
- * 
+ *
  *  <pre>
  *  &lt;mx:ArrayList
  *  <b>Properties</b>
  *  source="null"
  *  /&gt;
  *  </pre>
- * 
+ *
  *  @langversion 3.0
  *  @playerversion Flash 10
  *  @playerversion AIR 1.5
@@ -96,15 +100,15 @@ public class ArrayList extends EventDispatcher
     //--------------------------------------------------------------------------
     //
     // Constructor
-    // 
+    //
     //--------------------------------------------------------------------------
 
     /**
      *  Construct a new ArrayList using the specified array as its source.
      *  If no source is specified an empty array will be used.
-     * 
+     *
      *  @param source The Array to use as a source for the ArrayList.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -122,7 +126,7 @@ public class ArrayList extends EventDispatcher
     //--------------------------------------------------------------------------
     //
     // Variables
-    // 
+    //
     //--------------------------------------------------------------------------
 
     /**
@@ -131,19 +135,19 @@ public class ArrayList extends EventDispatcher
      */
     private var resourceManager:IResourceManager =
         ResourceManager.getInstance();
-                                    
+        
     /**
-     *  @private 
+     *  @private
      *  Indicates if events should be dispatched.
      *  calls to enableEvents() and disableEvents() effect the value when == 0
-     *  events should be dispatched. 
+     *  events should be dispatched.
      */
     private var _dispatchEvents:int = 0;
 
     //--------------------------------------------------------------------------
     //
     // Properties
-    // 
+    //
     //--------------------------------------------------------------------------
     
     //----------------------------------
@@ -154,11 +158,11 @@ public class ArrayList extends EventDispatcher
     
     /**
      *  Get the number of items in the list.  An ArrayList should always
-     *  know its length so it shouldn't return -1, though a subclass may 
+     *  know its length so it shouldn't return -1, though a subclass may
      *  override that behavior.
      *
      *  @return int representing the length of the source.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -183,16 +187,16 @@ public class ArrayList extends EventDispatcher
     private var _source:Array;
     
     /**
-     *  The source array for this ArrayList.  
-     *  Any changes done through the IList interface will be reflected in the 
-     *  source array.  
+     *  The source array for this ArrayList.
+     *  Any changes done through the IList interface will be reflected in the
+     *  source array.
      *  If no source array was supplied the ArrayList will create one internally.
-     *  Changes made directly to the underlying Array (e.g., calling 
-     *  <code>theList.source.pop()</code> will not cause <code>CollectionEvents</code> 
+     *  Changes made directly to the underlying Array (e.g., calling
+     *  <code>theList.source.pop()</code> will not cause <code>CollectionEvents</code>
      *  to be dispatched.
      *
      *  @return An Array that represents the underlying source.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -237,20 +241,20 @@ public class ArrayList extends EventDispatcher
     
     /**
      *  @private
-     *  Storage for the UID String. 
+     *  Storage for the UID String.
      */
     private var _uid:String;
     
     /**
      *  Provides access to the unique id for this list.
-     *  
-     *  @return String representing the internal uid. 
-     *  
+     *
+     *  @return String representing the internal uid.
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
      *  @productversion Flex 3
-     */  
+     */
     public function get uid():String
     {
 		if (!_uid) {
@@ -267,13 +271,13 @@ public class ArrayList extends EventDispatcher
     //--------------------------------------------------------------------------
     //
     // Methods
-    // 
+    //
     //--------------------------------------------------------------------------
 
 	/**
 	 *  Converts an Array List to JavaScript Object Notation (JSON) format.
 	 * 	Called by the JSON.stringify() method and should not be called directly.
-	 *  
+	 *
 	 *  @langversion 3.0
 	 *  @playerversion Flash 11
 	 *  @playerversion AIR 3.0
@@ -286,15 +290,15 @@ public class ArrayList extends EventDispatcher
 	
     /**
      *  Get the item at the specified index.
-     * 
+     *
      *  @param  index the index in the list from which to retrieve the item
      *  @param  prefetch int indicating both the direction and amount of items
      *          to fetch during the request should the item not be local.
      *  @return the item at that index, null if there is none
-     *  @throws ItemPendingError if the data for that index needs to be 
+     *  @throws ItemPendingError if the data for that index needs to be
      *                           loaded from a remote location
      *  @throws RangeError if the index &lt; 0 or index &gt;= length
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -309,20 +313,20 @@ public class ArrayList extends EventDispatcher
             throw new RangeError(message);
 			// return null;
         }
-            
+        
         return source[index];
     }
     
     /**
-     *  Place the item at the specified index.  
-     *  If an item was already at that index the new item will replace it and it 
+     *  Place the item at the specified index.
+     *  If an item was already at that index the new item will replace it and it
      *  will be returned.
      *
      *  @param  item the new value for the index
      *  @param  index the index at which to place the item
      *  @return the item that was replaced, null if none
      *  @throws RangeError if index is less than 0 or greater than or equal to length
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -330,7 +334,7 @@ public class ArrayList extends EventDispatcher
      */
     public function setItemAt(item:Object, index:int):Object
     {
-        if (index < 0 || index >= length) 
+        if (index < 0 || index >= length)
         {
             var message:String = resourceManager.getString(
                 "collections", "outOfBounds", [ index ]);
@@ -343,14 +347,14 @@ public class ArrayList extends EventDispatcher
         stopTrackUpdates(oldItem);
         startTrackUpdates(item);
         
-        //dispatch the appropriate events 
+        //dispatch the appropriate events
         if (_dispatchEvents == 0)
         {
-            var hasCollectionListener:Boolean = 
+            var hasCollectionListener:Boolean =
                 hasEventListener(CollectionEvent.COLLECTION_CHANGE);
-            var hasPropertyListener:Boolean = 
+            var hasPropertyListener:Boolean =
                 hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE);
-            var updateInfo:PropertyChangeEvent; 
+            var updateInfo:PropertyChangeEvent;
             
             if (hasCollectionListener || hasPropertyListener)
             {
@@ -376,15 +380,15 @@ public class ArrayList extends EventDispatcher
                 dispatchEvent(updateInfo);
             }
         }
-        return oldItem;    
+        return oldItem;
     }
     
     /**
      *  Add the specified item to the end of the list.
      *  Equivalent to addItemAt(item, length);
-     * 
+     *
      *  @param item the item to add
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -396,13 +400,13 @@ public class ArrayList extends EventDispatcher
     }
     
     /**
-     *  Add the item at the specified index.  
-     *  Any item that was after this index is moved out by one.  
-     * 
+     *  Add the item at the specified index.
+     *  Any item that was after this index is moved out by one.
+     *
      *  @param item the item to place at the index
      *  @param index the index at which to place the item
      *  @throws RangeError if index is less than 0 or greater than the length
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -438,7 +442,7 @@ public class ArrayList extends EventDispatcher
     
     /**
      *  @copy mx.collections.ListCollectionView#addAll()
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -451,7 +455,7 @@ public class ArrayList extends EventDispatcher
     
     /**
      *  @copy mx.collections.ListCollectionView#addAllAt()
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -486,13 +490,13 @@ public class ArrayList extends EventDispatcher
     
     /**
      *  Return the index of the item if it is in the list such that
-     *  getItemAt(index) == item.  
-     *  Note that in this implementation the search is linear and is therefore 
+     *  getItemAt(index) == item.
+     *  Note that in this implementation the search is linear and is therefore
      *  O(n).
-     * 
+     *
      *  @param item the item to find
      *  @return the index of the item, -1 if the item is not in the list.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -508,7 +512,7 @@ public class ArrayList extends EventDispatcher
      *
      *  @param  item Object reference to the item that should be removed.
      *  @return Boolean indicating if the item was removed.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -525,13 +529,13 @@ public class ArrayList extends EventDispatcher
     }
     
     /**
-     *  Remove the item at the specified index and return it.  
+     *  Remove the item at the specified index and return it.
      *  Any items that were after this index are now one index earlier.
      *
      *  @param index The index from which to remove the item.
      *  @return The item that was removed.
      *  @throws RangeError if index &lt; 0 or index &gt;= length.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -567,9 +571,9 @@ public class ArrayList extends EventDispatcher
         return removed;
     }
     
-    /** 
+    /**
      *  Remove all items from the list.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -587,14 +591,14 @@ public class ArrayList extends EventDispatcher
 
             source.splice(0, length);
             internalDispatchEvent(CollectionEventKind.RESET);
-        }    
+        }
     }
     
     /**
-     *  Notify the view that an item has been updated.  
-     *  This is useful if the contents of the view do not implement 
-     *  <code>IEventDispatcher</code>.  
-     *  If a property is specified the view may be able to optimize its 
+     *  Notify the view that an item has been updated.
+     *  This is useful if the contents of the view do not implement
+     *  <code>IEventDispatcher</code>.
+     *  If a property is specified the view may be able to optimize its
      *  notification mechanism.
      *  Otherwise it may choose to simply refresh the whole view.
      *
@@ -613,14 +617,14 @@ public class ArrayList extends EventDispatcher
      *  @see mx.events.CollectionEvent
      *  @see mx.core.IPropertyChangeNotifier
      *  @see mx.events.PropertyChangeEvent
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
      *  @productversion Flex 3
      */
-     public function itemUpdated(item:Object, property:Object = null, 
-                                 oldValue:Object = null, 
+     public function itemUpdated(item:Object, property:Object = null,
+                                 oldValue:Object = null,
                                  newValue:Object = null):void
     {
         var event:PropertyChangeEvent = new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
@@ -638,23 +642,23 @@ public class ArrayList extends EventDispatcher
         }
 
         itemUpdateHandler(event);
-    }    
+    }
     
     /**
      *  Return an Array that is populated in the same order as the IList
-     *  implementation.  
+     *  implementation.
      *
      *  @return An Array populated in the same order as the IList
      *  implementation.
-     * 
+     *
      *  @throws ItemPendingError if the data is not yet completely loaded
      *  from a remote location
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
      *  @productversion Flex 3
-     */ 
+     */
     public function toArray():Array
     {
         return source.concat();
@@ -664,25 +668,25 @@ public class ArrayList extends EventDispatcher
      *  Ensures that only the source property is serialized.
      *  @private
      */
-//    public function readExternal(input:IDataInput):void
-//    {
-//        source = input.readObject();
-//    }
+    public function readExternal(input:IDataInput):void
+    {
+       source = input.readObject();
+    }
     
     /**
      *  Ensures that only the source property is serialized.
      *  @private
      */
-//    public function writeExternal(output:IDataOutput):void
-//    {
-//        output.writeObject(_source);
-//    }
+    public function writeExternal(output:IDataOutput):void
+    {
+        output.writeObject(_source);
+    }
 
     /**
      *  Pretty prints the contents of this ArrayList to a string and returns it.
      *
      *  @return A String containing the contents of the ArrayList.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -693,19 +697,19 @@ public class ArrayList extends EventDispatcher
         if (source)
             return source.toString();
        else
-           return getQualifiedClassName(this); 
+           return getQualifiedClassName(this);
 		// return "<ArrayList>";
-    }   
+    }
     
     //--------------------------------------------------------------------------
     //
     // Internal Methods
-    // 
+    //
     //--------------------------------------------------------------------------
 
     /**
      *  Enables event dispatch for this list.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -722,7 +726,7 @@ public class ArrayList extends EventDispatcher
      *  Disables event dispatch for this list.
      *  To re-enable events call enableEvents(), enableEvents() must be called
      *  a matching number of times as disableEvents().
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -739,7 +743,7 @@ public class ArrayList extends EventDispatcher
      *  @param kind String indicates what the kind property of the event should be
      *  @param item Object reference to the item that was added or removed
      *  @param location int indicating where in the source the item was added.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -760,7 +764,7 @@ public class ArrayList extends EventDispatcher
             }
 
             // now dispatch a complementary PropertyChangeEvent
-            if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE) && 
+            if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE) &&
                (kind == CollectionEventKind.ADD || kind == CollectionEventKind.REMOVE))
             {
                 var objEvent:PropertyChangeEvent = new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
@@ -780,12 +784,12 @@ public class ArrayList extends EventDispatcher
      *  Wraps it in a <code>CollectionEventKind.UPDATE</code> object.
      *
      *  @param event The event object for the <code>PropertyChangeEvent</code>.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
      *  @productversion Flex 3
-     */    
+     */
     protected function itemUpdateHandler(event:PropertyChangeEvent):void
     {
         internalDispatchEvent(CollectionEventKind.UPDATE, event);
@@ -799,13 +803,13 @@ public class ArrayList extends EventDispatcher
         }
     }
     
-    /** 
-     *  If the item is an IEventDispatcher, watch it for updates.  
-     *  This method is called by the <code>addItemAt()</code> method, 
+    /**
+     *  If the item is an IEventDispatcher, watch it for updates.
+     *  This method is called by the <code>addItemAt()</code> method,
      *  and when the source is initially assigned.
      *
      *  @param item The item passed to the <code>addItemAt()</code> method.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
@@ -820,14 +824,14 @@ public class ArrayList extends EventDispatcher
         }
     }
     
-    /** 
+    /**
      *  If the item is an IEventDispatcher, stop watching it for updates.
-     *  This method is called by the <code>removeItemAt()</code> and 
+     *  This method is called by the <code>removeItemAt()</code> and
      *  <code>removeAll()</code> methods, and before a new
      *  source is assigned.
      *
      *  @param item The item passed to the <code>removeItemAt()</code> method.
-     *  
+     *
      *  @langversion 3.0
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
diff --git a/frameworks/projects/Network/src/main/royale/NetworkClasses.as b/frameworks/projects/Network/src/main/royale/NetworkClasses.as
index 902c70e..7fcd4f9 100644
--- a/frameworks/projects/Network/src/main/royale/NetworkClasses.as
+++ b/frameworks/projects/Network/src/main/royale/NetworkClasses.as
@@ -17,7 +17,7 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 package
-{   
+{
     /**
     *  @private
     *  This class is used to link additional classes into Network.swc
@@ -25,7 +25,7 @@ package
     *  from the classes specified in manifest.xml.
     */
     internal class NetworkClasses
-    {	
+    {
         import org.apache.royale.net.URLLoader; URLLoader;
         import org.apache.royale.net.URLBinaryLoader; URLBinaryLoader;
         import org.apache.royale.net.HTTPConstants; HTTPConstants;
@@ -42,6 +42,13 @@ package
         import org.apache.royale.net.remoting.messages.RemotingMessage; RemotingMessage;
 
         import org.apache.royale.net.remoting.messages.RoyaleClient; RoyaleClient;
+	
+		import org.apache.royale.net.remoting.amf.AMFBinaryData; AMFBinaryData;
+		import org.apache.royale.net.utils.IDataInput; IDataInput;
+		import org.apache.royale.net.utils.IDataOutput; IDataOutput;
+		import org.apache.royale.net.utils.IExternalizable; IExternalizable;
+		import org.apache.royale.net.utils.IDynamicPropertyWriter; IDynamicPropertyWriter;
+		import org.apache.royale.net.utils.IDynamicPropertyOutput; IDynamicPropertyOutput;
         
         import org.apache.royale.reflection.registerClassAlias;
         //RpcClassAliasInitializer
diff --git a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/CompressedRemoteObject.as b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/CompressedRemoteObject.as
index b9a7aac..19e86d2 100644
--- a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/CompressedRemoteObject.as
+++ b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/CompressedRemoteObject.as
@@ -31,7 +31,7 @@ package org.apache.royale.net
      *
      * It deserializes the compressed ByteArray in order to optimize the transfer time.
      * TOOD improve to serialize the sending.
-     * 
+     *
      */
     public class CompressedRemoteObject extends RemoteObject
     {
@@ -49,9 +49,9 @@ package org.apache.royale.net
 
         /**
          * disable the compression if true
-         * 
+         *
          * defaults to false
-         * 
+         *
          * @royalesuppresspublicvarwarning
          */
         public static var disableCompression:Boolean;
@@ -65,7 +65,7 @@ package org.apache.royale.net
                     var bytearray:Uint8Array = new Uint8Array(param.body);
 
                     // --- uncompress the bytearray to get the real object (tree) and create the AMFBinaryData with it
-                    var data:AMFBinaryData = new AMFBinaryData(window["pako"]["inflate"](bytearray));
+                    var data:AMFBinaryData = new AMFBinaryData(window["pako"]["inflate"](bytearray).buffer);
                     param.body = data.readObject();
                 }
                 // --- dispatch the ResultEvent like in the standard RemoteObject with the inflated result object
@@ -86,4 +86,4 @@ package org.apache.royale.net
             }
 		}
     }
-}
\ No newline at end of file
+}
diff --git a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFBinaryData.as b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFBinaryData.as
deleted file mode 100644
index db1a4e9..0000000
--- a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFBinaryData.as
+++ /dev/null
@@ -1,1299 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-////////////////////////////////////////////////////////////////////////////////
-/***
- * Based on the
- * AMF JavaScript library by Emil Malinov https://github.com/emilkm/amfjs
- */
-package org.apache.royale.net.remoting.amf {
-	import org.apache.royale.reflection.getAliasByClass;
-	import org.apache.royale.reflection.getClassByAlias;
-	import org.apache.royale.net.utils.IDataInput;
-	import org.apache.royale.net.utils.IDataOutput;
-	import org.apache.royale.utils.BinaryData;
-	
-	/**
-	 *  A version of BinaryData specific to AMF.
-	 *
-	 *  @langversion 3.0
-	 *  @playerversion Flash 9
-	 *  @playerversion AIR 1.1
-	 *  @productversion BlazeDS 4
-	 *  @productversion LCDS 3
-	 *
-	 *  @royalesuppresspublicvarwarning
-	 */
-	public class AMFBinaryData implements IDataInput, IDataOutput {
-		//--------------------------------------------------------------------------
-		//
-		// Class Constants
-		//
-		//--------------------------------------------------------------------------
-		
-		private static var _debug:Boolean = false;
-		
-		public static function get DEBUG():Boolean {
-			return _debug;
-		}
-		
-		public static function set DEBUG(value:Boolean):void {
-			_debug = value;
-		}
-		
-		public static const CLASS_ALIAS:String = "_explicitType";
-		
-		public static const EMPTY_STRING:String = "";
-		public static const NULL_STRING:String = "null";
-		
-		public static const AMF0_OBJECT_ENCODING:int = 0;
-		
-		public static const AMF0_NUMBER:int = 0;
-		public static const AMF0_BOOLEAN:int = 1;
-		public static const AMF0_STRING:int = 2;
-		public static const AMF0_OBJECT:int = 3;
-		public static const AMF0_MOVIECLIP:int = 4;
-		public static const AMF0_NULL:int = 5;
-		public static const AMF0_UNDEFINED:int = 6;
-		public static const AMF0_REFERENCE:int = 7;
-		public static const AMF0_MIXEDARRAY:int = 8; //ECMAArray
-		public static const AMF0_OBJECTEND:int = 9;
-		public static const AMF0_ARRAY:int = 10; //StrictArray
-		public static const AMF0_DATE:int = 11;
-		public static const AMF0_LONGSTRING:int = 12;
-		public static const AMF0_UNSUPPORTED:int = 13;
-		public static const AMF0_RECORDSET:int = 14;
-		public static const AMF0_XMLDOCUMENT:int = 15;
-		public static const AMF0_TYPEDOBJECT:int = 16;
-		public static const AMF0_AMF3:int = 17;
-		
-		public static const AMF3_OBJECT_ENCODING:int = 3;
-		
-		public static const AMF3_UNDEFINED:int = 0;
-		public static const AMF3_NULL:int = 1;
-		public static const AMF3_BOOLEAN_FALSE:int = 2;
-		public static const AMF3_BOOLEAN_TRUE:int = 3;
-		public static const AMF3_INTEGER:int = 4;
-		public static const AMF3_DOUBLE:int = 5;
-		public static const AMF3_STRING:int = 6;
-		public static const AMF3_XMLDOCUMENT:int = 7;
-		public static const AMF3_DATE:int = 8;
-		public static const AMF3_ARRAY:int = 9;
-		public static const AMF3_OBJECT:int = 10;
-		public static const AMF3_XML:int = 11;
-		public static const AMF3_BYTEARRAY:int = 12;
-		public static const AMF3_VECTOR_INT:int = 13;
-		public static const AMF3_VECTOR_UINT:int = 14;
-		public static const AMF3_VECTOR_DOUBLE:int = 15;
-		public static const AMF3_VECTOR_OBJECT:int = 16;
-		public static const AMF3_DICTIONARY:int = 17;
-		
-		
-		public static const UNKNOWN_CONTENT_LENGTH:int = 1;
-		
-		public static const UINT29_MASK:int = 536870911;
-		public static const INT28_MAX_VALUE:int = 268435455;
-		public static const INT28_MIN_VALUE:int = -268435456;
-		public static const UINT_MAX_VALUE:uint = 4294967295;
-		public static const UINT_MIN_VALUE:uint = 0;
-		
-		
-		public static const POW_2_20:Number = Math.pow(2, 20);
-		public static const POW_2_52:Number = Math.pow(2, 52);
-		public static const POW_2_52N:Number = Math.pow(2, -52);
-		
-		
-		public static var writeArrayCollectionReadArrayList:Boolean = true;
-		public static var addAliasInfoToAnonymousObjects:Boolean = false;
-		
-		//--------------------------------------------------------------------------
-		//
-		// Constructor
-		//
-		//--------------------------------------------------------------------------
-		
-		/**
-		 *  Constructs an uninitialized AMFBinaryData.
-		 *
-		 *  @langversion 3.0
-		 *  @playerversion Flash 9
-		 *  @playerversion AIR 1.1
-		 *  @productversion BlazeDS 4
-		 *  @productversion LCDS 3
-		 */
-		public function AMFBinaryData(data:Array = null) {
-			// TODO: (aharui) try to share code with BinaryData.
-			// BinaryData has different methods and also
-			// has ENDIAN code which AMF doesn't seem to need.
-			super();
-			if (data) {
-				this.data = data;
-			}
-			
-		}
-		
-		//--------------------------------------------------------------------------
-		//
-		// Variables
-		//
-		//--------------------------------------------------------------------------
-		
-		public var treatUnderscoresAsPrivateFields:Boolean = false;
-		
-		public var data:Array = [];
-		
-		private var objects:Array = [];
-		
-		private var traits:Object = {};
-		
-		private var strings:Object = {};
-		
-		private var stringCount:uint = 0;
-		private var traitCount:uint = 0;
-		private var objectCount:uint = 0;
-		
-		public var pos:uint = 0;
-		
-		public function write(v:uint):void {
-			data.push(v);
-		}
-		
-		public function writeShort(v:uint):void {
-			write((v >>> 8) & 255);
-			write((v >>> 0) & 255);
-		}
-		
-		public function writeUTF(v:String, asAmf:Boolean = false):uint {
-			var bytearr:Array = [];
-			var strlen:uint = v.length;
-			var utflen:uint = 0;
-			
-			for (var i:uint = 0; i < strlen; i++) {
-				var c1:uint = v.charCodeAt(i);
-				//var enc = null;
-				
-				if (c1 < 128) {
-					utflen++;
-					bytearr.push(c1);
-					//end++;
-				} else if (c1 > 127 && c1 < 2048) {
-					utflen += 2;
-					bytearr.push(192 | (c1 >> 6));
-					if (asAmf)
-						bytearr.push(128 | ((c1 >> 0) & 63));
-					else
-						bytearr.push(128 | (c1 & 63));
-				} else if ((c1 & 0xF800) !== 0xD800) {
-					utflen += 3;
-					bytearr.push(224 | (c1 >> 12));
-					bytearr.push(128 | ((c1 >> 6) & 63));
-					if (asAmf)
-						bytearr.push(128 | ((c1 >> 0) & 63));
-					else
-						bytearr.push(128 | (c1 & 63));
-				} else {
-					utflen += 4;
-					if ((c1 & 0xFC00) !== 0xD800) {
-						throw new RangeError('Unmatched trail surrogate at ' + i);
-					}
-					var c2:uint = v.charCodeAt(++i);
-					if ((c2 & 0xFC00) !== 0xDC00) {
-						throw new RangeError('Unmatched lead surrogate at ' + (i - 1));
-					}
-					c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
-					bytearr.push(240 | (c1 >> 18));
-					bytearr.push(128 | ((c1 >> 12) & 63));
-					bytearr.push((c1 >> 6) & 63);
-					if (asAmf)
-						bytearr.push(128 | ((c1 >> 0) & 63));
-					else
-						bytearr.push(128 | (c1 & 63));
-				}
-			}
-			
-			if (asAmf)
-				writeUInt29((utflen << 1) | 1);
-			else {
-				bytearr.unshift(utflen & 255);
-				bytearr.unshift((utflen >>> 8) & 255);
-			}
-			
-			writeAll(bytearr);
-			return asAmf ? utflen : utflen + 2;
-		}
-		
-		public function writeUInt29(v:uint):void {
-			if (v < 128) {
-				this.write(v);
-			} else if (v < 16384) {
-				this.write(((v >> 7) & 127) | 128);
-				this.write(v & 127);
-			} else if (v < 2097152) {
-				this.write(((v >> 14) & 127) | 128);
-				this.write(((v >> 7) & 127) | 128);
-				this.write(v & 127);
-			} else if (v < 0x40000000) {
-				this.write(((v >> 22) & 127) | 128);
-				this.write(((v >> 15) & 127) | 128);
-				this.write(((v >> 8) & 127) | 128);
-				this.write(v & 255);
-			} else {
-				throw "Integer out of range: " + v;
-			}
-		}
-		
-		public function writeAll(bytes:Array):void {
-			for (var i:uint = 0; i < bytes.length; i++) {
-				this.write(bytes[i]);
-			}
-		}
-		
-		public function writeBoolean(v:Boolean):void {
-			this.write(v ? 1 : 0);
-		}
-		
-		public function writeInt(v:int):void {
-			this.write((v >>> 24) & 255);
-			this.write((v >>> 16) & 255);
-			this.write((v >>> 8) & 255);
-			this.write((v >>> 0) & 255);
-		}
-		
-		public function writeUInt32(v:int):void {
-		//	v < 0 && (v = -(v ^ UINT_MAX_VALUE) - 1);
-			//avoid compiler warning after numeric coercion changes:
-			if (v <0) {
-				v = -(v ^ UINT_MAX_VALUE) - 1;
-			}
-			v &= UINT_MAX_VALUE;
-			this.write((v >>> 24) & 255);
-			this.write((v >>> 16) & 255);
-			this.write((v >>> 8) & 255);
-			this.write((v & 255));
-		}
-		
-		private function getDouble(v:Number):Array {
-			var r:Array = [0, 0];
-			if (v != v) {
-				r[0] = -524288;
-				return r;
-			}
-			var d:int = v < 0 || v === 0 && 1 / v < 0 ? -2147483648 : 0;
-			v = Math.abs(v);
-			if (v === Number.POSITIVE_INFINITY) {
-				r[0] = d | 2146435072;
-				return r;
-			}
-			for (var e:int = 0; v >= 2 && e <= 1023;) {
-				e++;
-				v /= 2;
-			}
-			for (; v < 1 && e >= -1022;) {
-				e--;
-				v *= 2;
-			}
-			e += 1023;
-			if (e == 2047) {
-				r[0] = d | 2146435072;
-				return r;
-			}
-			var i:Number;
-			if (e == 0) {
-				i = v * Math.pow(2, 23) / 2;
-				v = Math.round(v * POW_2_52 / 2);
-			} else {
-				i = v * POW_2_20 - POW_2_20;
-				v = Math.round(v * POW_2_52 - POW_2_52);
-			}
-			r[0] = d | e << 20 & 2147418112 | i & 1048575;
-			r[1] = v;
-			return r;
-		}
-		
-		public function writeDouble(v:Number):void {
-			var parts:Array = getDouble(v);
-			this.writeUInt32(parts[0]);
-			this.writeUInt32(parts[1]);
-		}
-		
-		public function getResult():String {
-			return data.join("");
-		}
-		
-		public function getData():Array {
-			return data;
-		}
-		
-		public function reset():void {
-			this.objects = [];
-			this.objectCount = 0;
-			this.traits = {};
-			this.traitCount = 0;
-			this.strings = {};
-			this.stringCount = 0;
-			
-		}
-		
-		private function writeStringWithoutType(v:String):void {
-			if (v.length == 0) {
-				this.writeUInt29(1);
-			} else {
-				if (!this.stringByReference(v)) {
-					this.writeUTF(v, true);
-				}
-			}
-		}
-		
-		private function stringByReference(v:String):Boolean {
-			const strIndex:* = this.strings[v];
-			const found:Boolean = strIndex !== undefined;
-			if (found) {
-				const ref:uint = strIndex;
-				this.writeUInt29(ref << 1);
-			} else {
-				this.strings[v] = this.stringCount++;
-			}
-			return found;
-		}
-		
-		public function objectByReference(v:Object):Boolean {
-			const ref:int = objects.indexOf(v);
-			const found:Boolean = ref !== -1;
-			if (found) {
-				this.writeUInt29(ref << 1);
-			} else {
-				this.objects.push(v);
-				this.objectCount++;
-			}
-			return found;
-		}
-		
-		private function traitsByReference(props:Array, alias:String):Boolean {
-			//@todo review this. Don't think it is necessary to do the long joins with the props
-			//maybe alias alone is enough...?
-			const s:String = alias + "|" + props.join("|");
-			const traitsIndex:* = this.traits[s];
-			const found:Boolean = traitsIndex !== undefined;
-			if (found) {
-				const ref:uint = traitsIndex;
-				this.writeUInt29((ref << 2) | 1);
-			} else {
-				this.traits[s] = this.traitCount++;
-			}
-			return found;
-		}
-		
-		private function writeAmfInt(v:int):void {
-			if (v >= INT28_MIN_VALUE && v <= INT28_MAX_VALUE) {
-				v = v & UINT29_MASK;
-				this.write(AMF3_INTEGER);
-				this.writeUInt29(v);
-			} else {
-				this.write(AMF3_DOUBLE);
-				this.writeDouble(v);
-			}
-		}
-		
-		private function writeDate(v:Date):void {
-			this.write(AMF3_DATE);
-			if (!this.objectByReference(v)) {
-				this.writeUInt29(1);
-				this.writeDouble(v.getTime());
-			}
-		}
-		
-		private function filterSerializableMembers(fieldSet:Object, accessChecks:Object, localTraits:Traits, asAccessors:Boolean = false, excludeTransient:Boolean = true):Array {
-			var l:uint;
-			var metas:Array;
-			var exclude:Boolean;
-			var fieldName:String;
-			const into:Array = localTraits.props;
-			
-			for (fieldName in fieldSet) {
-				//exclude all static props
-				if (fieldName.charAt(0) == '|') continue;
-				var field:Object = fieldSet[fieldName];
-				exclude = false;
-				if (asAccessors) {
-					exclude = field.access != 'readwrite';
-					if (exclude && into.indexOf(fieldName) == -1) { //<-- if at some level we already have read-write access, then that wins
-						//check: does it combine to provide 'readwite' permissions via accessChecks through inheritance chain
-						if (accessChecks[fieldName] && accessChecks[fieldName] != field.access) {
-							//readonly or writeonly overridde at one level and different at another == readwrite
-							exclude = false;
-						} else {
-							if (!accessChecks[fieldName]) {
-								//cache for subsequent cross-checks as above
-								accessChecks[fieldName] = field.access;
-							}
-						}
-					}
-				}
-				if (!exclude && excludeTransient && field.metadata != null) {
-					//exclude anything marked as Transient
-					metas = field.metadata();
-					l = metas.length;
-					while (l--) {
-						if (metas[l].name == 'Transient') {
-							exclude = true;
-						}
-					}
-					if (exclude && into.indexOf(fieldName) != -1) {
-						//?possible case where it is marked transient on an ancestor but not in a subclass override
-						//it will not have been excluded when processing the subclass, which occurs first, so remove it now
-						//@todo untested : check this scenario, assume it should be removed
-						into.splice(into.indexOf(fieldName), 1);
-					}
-				}
-				if (!exclude) {
-					//set up null/undefined value lookups for undefined field values (when encoding)
-					var nullValues:Object = localTraits.nullValues;
-					if (field.type == 'Number') {
-						nullValues[fieldName] = Number.NaN;
-					} else if (field.type == 'Boolean') {
-						nullValues[fieldName] = false;
-					} else if (field.type == 'int' || field.type == 'uint') {
-						nullValues[fieldName] = 0;
-					} else if (field.type == '*') {
-						nullValues[fieldName] = undefined;
-					} else {
-						nullValues[fieldName] = null;
-					}
-					into.push(fieldName);
-				}
-			}
-			return into;
-		}
-		
-		private function populateSerializableMembers(reflectionInfo:Object, accessChecks:Object, localTraits:Traits):Array {
-			if (!reflectionInfo) return localTraits.props;
-			var fields:Object = reflectionInfo.variables();
-			filterSerializableMembers(fields, accessChecks, localTraits, false, true);
-			fields = reflectionInfo.accessors();
-			filterSerializableMembers(fields, accessChecks, localTraits, true, true);
-			return localTraits.props;
-		}
-		
-		private function getLocalTraitsInfo(instance:Object):Traits {
-			var classInfo:Object = instance.ROYALE_CLASS_INFO;
-			var originalClassInfo:Object;
-			var localTraits:Traits;
-			if (classInfo) {
-				if (classInfo.localTraits) {
-					//check alignment with any registerClassAlias changes that might have happened
-					//implementation note: @todo a class may have more than one alias point to it
-					//@todo integrate with reflection / registerClassAlias changes (either here or there)
-					return classInfo.localTraits;
-				}
-				originalClassInfo = classInfo;
-				localTraits = new Traits();
-				var alias:String = getAliasByClass(instance.constructor as Class); //<- @todo possible optimization: registerClassAlias implementation stores in the classInfo Object, access directly
-				if (alias) localTraits.alias = alias;
-				else localTraits.alias = '';
-				localTraits.qName = classInfo.names[0].qName;
-				localTraits.dynamic = false;
-				localTraits.externalizable = /* @todo check interfaces for Externalizable */ false;
-
-//Temporary Special Casing
-//a) automatically recognise ArrayCollection as externalized
-//b) support ArrayList < --- > ArrayCollection conversions without alias mappings
-//This will be removed in favor of either original approaches or some custom alias remapping support
-				//so for now:
-				if (localTraits.qName == 'org.apache.royale.collections.ArrayList' ||
-						localTraits.alias == 'flex.messaging.io.ArrayCollection') {
-					localTraits.externalizable = true;
-				}
-				
-				if (localTraits.externalizable) {
-					localTraits.count = 0;
-				} else {
-					var accessChecks:Object = {};
-					var c:Object = instance;
-					while (classInfo) {
-						var reflectionInfo:Object = c.ROYALE_REFLECTION_INFO();
-						populateSerializableMembers(reflectionInfo, accessChecks, localTraits);
-						if (!c.constructor.superClass_ || !c.constructor.superClass_.ROYALE_CLASS_INFO)
-							break;
-						classInfo = c.constructor.superClass_.ROYALE_CLASS_INFO;
-						c = c.constructor.superClass_;
-					}
-					localTraits.count = localTraits.props.length;
-					//not required, but useful when testing:
-					localTraits.props.sort();
-				}
-				//cache in the classInfo for faster lookups next time
-				//@todo Greg to integrate with registerClassAlias so alias information is always aligned on teh cached localTraits
-				originalClassInfo.localTraits = localTraits;
-			} else {
-				//assume dynamic, anon object
-				
-				var anonFields:Array = [];
-				for (var key:String in instance) {
-					if (key !== "") {
-						if (treatUnderscoresAsPrivateFields && key.indexOf("_") === 0) continue;
-						anonFields.push(key);
-					}
-				}
-				localTraits = Traits.getDynObjectTraits(anonFields);
-				//not required, but useful when testing:
-				localTraits.props.sort();
-			}
-			return localTraits;
-		}
-		
-		
-		/**
-		 * @royaleignorecoercion Class
-		 * @royaleignorecoercion String
-		 * @royaleignorecoercion Number
-		 */
-		public function writeObject(v:*):void {
-			if (v == null) {
-				this.write(AMF3_NULL);
-				return;
-			}
-			if (v is Function) {
-				//output function value as undefined
-				this.write(AMF3_UNDEFINED);
-				return;
-			}
-			if (v is String) {
-				this.write(AMF3_STRING);
-				this.writeStringWithoutType(v as String);
-			} else if (v is Number) {
-				var n:Number = v as Number;
-				if (n === +n && n === (n | 0)) {
-					this.writeAmfInt(n);
-				} else {
-					this.write(AMF3_DOUBLE);
-					this.writeDouble(n);
-				}
-			} else if (v is Boolean)
-				this.write((v
-						? AMF3_BOOLEAN_TRUE
-						: AMF3_BOOLEAN_FALSE));
-			else if (v is Date)
-				this.writeDate(v as Date);
-			else {
-				if (v is Array) {
-					if (v.toString().indexOf("[Vector") == 0)
-						this.writeVector(v);
-					else
-						this.writeArray(v as Array);
-				} else writeObjectVariant(v);
-			}
-		}
-		
-		/**
-		 *
-		 * @royaleignorecoercion AMFBinaryData
-		 * @royaleignorecoercion Array
-		 */
-		private function writeObjectVariant(v:Object):void {
-			if (v is AMFBinaryData || v is BinaryData) {
-				this.write(AMF3_BYTEARRAY);
-				//@todo what if the source here is the same as the destination, i.e. v == this ?
-				var amfBinary:AMFBinaryData;
-				if (v is BinaryData) {
-					var source:Object = v.array;
-					COMPILE::JS {
-						source = Array.from(source);
-					}
-					amfBinary = new AMFBinaryData(source as Array);
-					trace('created AMFBinary from Binary');
-				} else amfBinary = AMFBinaryData(v);
-				var len:uint = amfBinary.data.length;
-				writeUInt29(len);
-				writeBytes(amfBinary, 0, len);
-				return;
-			}
-			
-			this.write(AMF3_OBJECT);
-			if (!this.objectByReference(v)) {
-				const localTraits:Traits = getLocalTraitsInfo(v);
-				if (!localTraits.alias || localTraits.dynamic) {
-					writeDynamicObject(v, localTraits);
-				} else {
-					writeTypedObject(v, localTraits);
-				}
-			}
-		}
-		
-		private function writeExternalized(v:Object, localTraits:Traits):void {
-			//Special case for now (temporary for ArrayCollection)
-			if (localTraits.alias == 'flex.messaging.io.ArrayCollection' ||
-					localTraits.alias == 'org.apache.royale.collections.ArrayList') {
-				writeObject(v.source);
-				return;
-			}
-			//@todo at implementor support  for IDataOutput-ish:
-			throw new Error('IExternalizables to be done: Not yet available');
-			//v.writeExternal(this);
-		}
-		
-		
-		private function writeTypedObject(v:Object, localTraits:Traits):void {
-			//we normally only end up in this code if we have an alias, but use qName as a backstop
-			//one possibility is that we could offer an 'alias-free' clientside switch to use qNames only as a future feature
-			//but implementation inside swf netconnection etc, could be a challenge
-			var encodedName:String = localTraits.alias && localTraits.alias.length ? localTraits.alias : localTraits.qName;
-			
-			//@todo temporary special-casing for now, consider as a feature
-			if (localTraits.externalizable && writeArrayCollectionReadArrayList && localTraits.qName == 'org.apache.royale.collections.ArrayList') {
-				//do the same for outbound ArrayList -- > written as ArrayCollection
-				encodedName = 'flex.messaging.io.ArrayCollection';
-			}
-			
-			if (!traitsByReference(localTraits.props, encodedName)) {
-				//@todo double-check that externalized count should be 0 (it seems it should be, but not verified)
-				this.writeUInt29(3 | (localTraits.externalizable ? 4 : 0) | (localTraits.dynamic ? 8 : 0) | (localTraits.count << 4));
-				this.writeStringWithoutType(encodedName);
-				
-				if (!localTraits.externalizable) {
-					var l:uint = localTraits.count;
-					for (var i:uint = 0; i < l; i++) {
-						this.writeStringWithoutType(localTraits.props[i]);
-					}
-				}
-			}
-			
-			if (localTraits.externalizable) {
-				writeExternalized(v, localTraits);
-			} else {
-				l = localTraits.count;
-				for (i = 0; i < l; i++) {
-					var val:* = v[localTraits.props[i]];
-					if (val === null || val === undefined) {
-						//coerce null values to the 'correct' types
-						val = localTraits.nullValues[localTraits.props[i]];
-						
-						//handle '*' type which can be undefined or explicitly null
-						if (val === undefined && v[localTraits.props[i]] === null) {
-							val = null;
-						}
-					}
-					this.writeObject(val);
-				}
-				
-				//@todo handle dynamic as well (either via compiler support, or maybe ES6 Proxy?)
-			}
-		}
-		
-		private function writeDynamicObject(v:Object, localTraits:Traits):void {
-			if (!this.traitsByReference([], '$DynObject$')) { //<-something to represent an anonymous object
-				this.writeUInt29(11 /* 3 | 8 == dynamic */);
-				this.writeStringWithoutType(EMPTY_STRING); //class name
-			}
-			var i:uint = 0;
-			var l:uint = localTraits.props.length;
-			for (; i < l; i++) {
-				this.writeStringWithoutType(localTraits.props[i]);
-				this.writeObject(v[localTraits.props[i]]);
-			}
-			this.writeStringWithoutType(EMPTY_STRING);
-		}
-		
-		
-		private function writeArray(v:Array):void {
-			this.write(AMF3_ARRAY);
-			var len:uint = v.length;
-			if (!this.objectByReference(v)) {
-				this.writeUInt29((len << 1) | 1);
-				this.writeUInt29(1); //empty string implying no named keys
-				if (len > 0) {
-					for (var i:uint = 0; i < len; i++) {
-						this.writeObject(v[i]);
-					}
-				}
-			}
-		}
-		
-		private function writeVector(v:Object):void {
-			this.write(v.type);
-			var i:uint;
-			var len:uint = v.length;
-			if (!this.objectByReference(v)) {
-				this.writeUInt29((len << 1) | 1);
-				this.writeBoolean(v.fixed);
-			}
-			if (v.type == AMF3_VECTOR_OBJECT) {
-				var className:String = "";
-				if (len > 0) {
-					// TODO: how much of the PHP logic can we do here
-					className = v[0].constructor.name;
-				}
-				this.writeStringWithoutType(className);
-				for (i = 0; i < len; i++) {
-					this.writeObject(v[i]);
-				}
-			} else if (v.type == AMF3_VECTOR_INT) {
-				for (i = 0; i < len; i++) {
-					this.writeInt(v[i]);
-				}
-			} else if (v.type == AMF3_VECTOR_UINT) {
-				for (i = 0; i < len; i++) {
-					this.writeUInt32(v[i]);
-				}
-			} else if (v.type == AMF3_VECTOR_DOUBLE) {
-				for (i = 0; i < len; i++) {
-					this.writeDouble(v[i]);
-				}
-			}
-		}
-		
-		
-		private var readerLog:Array = []
-		
-		public function flushReaderLog():String {
-			var out:String = readerLog.join("\n");
-			readerLog = [];
-			return out;
-		}
-		
-		public function read():uint {
-			//if (this.pos + 1 > this.datalen) { //this.data.length store in this.datalen
-			//  throw "Cannot read past the end of the data.";
-			//}
-			return this.data[this.pos++];
-		}
-		
-		public function readUIntN(n:int):uint {
-			var value:uint = this.read();
-			for (var i:int = 1; i < n; i++) {
-				value = (value << 8) | this.read();
-			}
-			return value;
-		}
-		
-		public function readUnsignedShort():uint {
-			var c1:uint = this.read();
-			var c2:uint = this.read();
-			return ((c1 << 8) + (c2 << 0));
-		}
-		
-		public function readInt():int {
-			var c1:int = this.read();
-			var c2:int = this.read();
-			var c3:int = this.read();
-			var c4:int = this.read();
-			return ((c1 << 24) + (c2 << 16) + (c3 << 8) + (c4 << 0));
-		}
-		
-		public function readUInt32():uint {
-			var c1:uint = this.read();
-			var c2:uint = this.read();
-			var c3:uint = this.read();
-			var c4:uint = this.read();
-			return (c1 * 0x1000000) + ((c2 << 16) | (c3 << 8) | c4);
-		}
-		
-		public function readUInt29():int {
-			var b:uint = this.read() & 255;
-			if (b < 128) {
-				return b;
-			}
-			var value:uint = (b & 127) << 7;
-			b = this.read() & 255;
-			if (b < 128)
-				return (value | b);
-			value = (value | (b & 127)) << 7;
-			b = this.read() & 255;
-			if (b < 128)
-				return (value | b);
-			value = (value | (b & 127)) << 8;
-			b = this.read() & 255;
-			return (value | b);
-		}
-		
-		public function readFully(buff:Array, start:int, length:int):void {
-			for (var i:int = start; i < length; i++) {
-				buff[i] = this.read();
-			}
-		}
-		
-		public function readUTF(length:uint = 0):String {
-			var utflen:uint = length ? length : this.readUnsignedShort();
-			var len:uint = this.pos + utflen;
-			var chararr:Array = [];
-			var c1:int = 0;
-			var seqlen:uint = 0;
-			
-			while (this.pos < len) {
-				c1 = this.read() & 0xFF;
-				seqlen = 0;
-				
-				if (c1 <= 0xBF) {
-					c1 = c1 & 0x7F;
-					seqlen = 1;
-				} else if (c1 <= 0xDF) {
-					c1 = c1 & 0x1F;
-					seqlen = 2;
-				} else if (c1 <= 0xEF) {
-					c1 = c1 & 0x0F;
-					seqlen = 3;
-				} else {
-					c1 = c1 & 0x07;
-					seqlen = 4;
-				}
-				
-				for (var i:int = 1; i < seqlen; ++i) {
-					c1 = c1 << 0x06 | this.read() & 0x3F;
-				}
-				
-				if (seqlen === 4) {
-					c1 -= 0x10000;
-					chararr.push(String.fromCharCode(0xD800 | c1 >> 10 & 0x3FF));
-					chararr.push(String.fromCharCode(0xDC00 | c1 & 0x3FF));
-				} else {
-					chararr.push(String.fromCharCode(c1));
-				}
-			}
-			
-			return chararr.join("");
-		}
-		
-		public function readObject():* {
-			var type:uint = this.read();
-			return this.readObjectValue(type);
-		}
-		
-		public function readString():String {
-			var ref:uint = this.readUInt29();
-			if ((ref & 1) == 0) {
-				return this.getString(ref >> 1);
-			} else {
-				var len:uint = (ref >> 1);
-				if (len == 0) {
-					return EMPTY_STRING;
-				}
-				var str:String = this.readUTF(len);
-				this.rememberString(str);
-				return str;
-			}
-		}
-		
-		private function rememberString(v:String):void {
-			this.strings[stringCount++] = v;
-		}
-		
-		private function getString(v:uint):String {
-			return this.strings[v];
-		}
-		
-		private function getObject(v:uint):Object {
-			
-			return this.objects[v];
-		}
-		
-		
-		private function getTraits(v:uint):Traits {
-			return this.traits[v] as Traits;
-		}
-		
-		private function rememberTraits(v:Traits):void {
-			this.traits[traitCount++] = v;
-		}
-		
-		
-		private function rememberObject(v:Object):void {
-			this.objects.push(v);
-		}
-		
-		private function readTraits(ref:uint):Traits {
-			var ti:Traits;
-			if ((ref & 3) == 1) {
-				ti = this.getTraits(ref >> 2);
-				return ti;
-			} else {
-				ti = new Traits();
-				ti.externalizable = ((ref & 4) == 4);
-				ti.dynamic = ((ref & 8) == 8);
-				ti.count = (ref >> 4);
-				var className:String = this.readString();
-				if (className != null && className != "") {
-					ti.alias = className;
-				}
-				
-				for (var i:int = 0; i < ti.count; i++) {
-					ti.props.push(this.readString());
-				}
-				
-				this.rememberTraits(ti);
-				return ti;
-			}
-		}
-		
-		
-		private function readExternalized(v:Object, decodedTraits:Traits):void {
-			
-			//Special case for now (temporary for ArrayCollection until it and ArrayList implement IExternalizable)
-			if (decodedTraits.alias == 'flex.messaging.io.ArrayCollection' ||
-					decodedTraits.alias == 'org.apache.royale.collections.ArrayList') {
-				//for now, only emulate a call to 'readExternal' as if it was already implemented
-				v.source = this.readObject();
-				return;
-			}
-			if (decodedTraits.alias == "DSC") {
-				trace('found');
-			}
-			//maybe check local traits first for Externalizable support before doing this:
-			//@todo check what ByteArray does if the traits that were read encode for externalizable and the local aliased class
-			//does not implement IExternalizable - probably throw an error in this case because the subsequent
-			//encoding format of bytes is not known and therefore is not 'skippable'/recoverable
-			
-			//@todo implement IExternalizable as a call to the IDataOutput-ish:
-			throw new Error("Not yet implemented")
-			//v.readExternal(this);
-		}
-		
-		private function readScriptObject():Object {
-			var ref:uint = this.readUInt29();
-			if ((ref & 1) == 0) {
-				//retrieve object from object reference table
-				return this.getObject(ref >> 1);
-			} else {
-				var decodedTraits:Traits = this.readTraits(ref);
-				if (decodedTraits.alias == "flex.messaging.io.ArrayCollection") {
-					if (writeArrayCollectionReadArrayList) {
-						//pretend to be ArrayList
-						decodedTraits = new Traits();
-						decodedTraits.externalizable = true;
-						decodedTraits.alias = 'org.apache.royale.collections.ArrayList';
-						decodedTraits.dynamic = false;
-						decodedTraits.count = 0;
-					}
-				} else {
-					if (decodedTraits.alias == "flex.messaging.io.ObjectProxy" ||
-							decodedTraits.alias == "DSK") {
-						decodedTraits.alias = '';
-						//@todo implement via IExternalizable
-					}
-				}
-				var obj:Object;
-				var localTraits:Traits;
-				if (decodedTraits.alias) {
-					var c:Class = getClassByAlias(decodedTraits.alias);
-					if (c) {
-						obj = new c();
-						localTraits = getLocalTraitsInfo(obj);
-					} else {
-						obj = {};
-						if (addAliasInfoToAnonymousObjects)
-							obj[CLASS_ALIAS] = decodedTraits.alias;
-					}
-				} else {
-					obj = {};
-				}
-				this.rememberObject(obj);
-				if (decodedTraits.externalizable) {
-					readExternalized(obj, decodedTraits);
-				} else {
-					const l:uint = decodedTraits.props.length;
-					for (var i:uint = 0; i < l; i++) {
-						var fieldValue:* = this.readObject();
-						var prop:String = decodedTraits.props[i];
-						//@todo if also is dynamic, then the exclusions below may not apply? requires investigation
-						if (!localTraits || localTraits.hasProp(prop)) {
-							obj[prop] = fieldValue;
-						} else {
-							if (_debug) {
-								trace('[AMFBinaryData] discarding unknown \'' + prop + '\' property value from decoded content', localTraits.qName + "<-->" + decodedTraits.alias);
-							}
-						}
-					}
-					if (decodedTraits.dynamic) {
-						for (; ;) {
-							var name:String = this.readString();
-							if (name == null || name.length == 0) {
-								break;
-							}
-							obj[name] = this.readObject();
-						}
-					}
-				}
-				return obj;
-			}
-		}
-		
-		/**
-		 * @royaleignorecoercion Array
-		 */
-		public function readArray():Array {
-			var ref:uint = this.readUInt29();
-			if ((ref & 1) == 0)
-				return this.getObject(ref >> 1) as Array;
-			var len:uint = (ref >> 1);
-			var map:Object = null;
-			var i:uint = 0;
-			while (true) {
-				var name:String = this.readString();
-				if (!name)
-					break;
-				if (!map) {
-					map = {};
-					this.rememberObject(map);
-				}
-				map[name] = this.readObject();
-			}
-			if (!map) {
-				var array:Array = new Array(len);
-				this.rememberObject(array);
-				for (i = 0; i < len; i++)
-					array[i] = this.readObject();
-				return array;
-			} else {
-				var amap:Array = [];
-				for (i = 0; i < len; i++)
-					amap[i] = this.readObject();
-				return amap;
-			}
-		}
-		
-		public function readDouble():Number {
-			var c1:uint = this.read() & 255;
-			var c2:uint = this.read() & 255;
-			if (c1 === 255) {
-				if (c2 >= 248) {
-					//one quiet NaN range (see https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html)
-					//skip next 6 bytes
-					pos += 6;
-					return Number.NaN;
-				}
-				
-				if (c2 === 240) {
-					//skip next 6 bytes
-					pos += 6;
-					return Number.NEGATIVE_INFINITY;
-				}
-			} else if (c1 === 127) {
-				if (c2 >= 248) {
-					//another quiet NaN range (see https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html)
-					//skip next 6 bytes
-					pos += 6;
-					return Number.NaN;
-				}
-				
-				if (c2 === 240) {
-					//skip next 6 bytes
-					pos += 6;
-					return Number.POSITIVE_INFINITY;
-				}
-			}
-			var c3:uint = this.read() & 255;
-			var c4:uint = this.read() & 255;
-			var c5:uint = this.read() & 255;
-			var c6:uint = this.read() & 255;
-			var c7:uint = this.read() & 255;
-			var c8:uint = this.read() & 255;
-			if (!c1 && !c2 && !c3 && !c4)
-				return 0;
-			var d:int = (c1 << 4 & 2047 | c2 >> 4) - 1023;
-			var e:String = ((c2 & 15) << 16 | c3 << 8 | c4).toString(2);
-			for (var i:uint = e.length; i < 20; i++)
-				e = "0" + e;
-			var f:String = ((c5 & 127) << 24 | c6 << 16 | c7 << 8 | c8).toString(2);
-			for (var j:uint = f.length; j < 31; j++)
-				f = "0" + f;
-			var g:Number = parseInt(e + (c5 >> 7 ? "1" : "0") + f, 2);
-			if (g == 0 && d == -1023)
-				return 0;
-			return (1 - (c1 >> 7 << 1)) * (1 + POW_2_52N * g) * Math.pow(2, d);
-		}
-		
-		/**
-		 * @royaleignorecoercion Array
-		 */
-		public function readDate():Date {
-			var ref:uint = this.readUInt29();
-			if ((ref & 1) == 0)
-				return this.getObject(ref >> 1) as Date;
-			var time:Number = this.readDouble();
-			var date:Date = new Date(time);
-			this.rememberObject(date);
-			return date;
-		}
-		
-		public function readByteArray():Array {
-			var ref:uint = this.readUInt29();
-			if ((ref & 1) == 0)
-				return this.getObject(ref >> 1) as Array;
-			else {
-				var len:uint = (ref >> 1);
-				var ba:Array = [];
-				this.readFully(ba, 0, len);
-				this.rememberObject(ba);
-				return ba;
-			}
-		}
-		
-		private function readAmf3Vector(type:uint):Object {
-			var ref:uint = this.readUInt29();
-			if ((ref & 1) == 0)
-				return this.getObject(ref >> 1);
-			var len:uint = (ref >> 1);
-			var vector:Array = toVector(type, [], this.readBoolean());
-			var i:uint;
-			if (type === AMF3_VECTOR_OBJECT) {
-				this.readString(); //className
-				for (i = 0; i < len; i++)
-					vector.push(this.readObject());
-			} else if (type === AMF3_VECTOR_INT) {
-				for (i = 0; i < len; i++)
-					vector.push(this.readInt());
-			} else if (type === AMF3_VECTOR_UINT) {
-				for (i = 0; i < len; i++)
-					vector.push(this.readUInt32());
-			} else if (type === AMF3_VECTOR_DOUBLE) {
-				for (i = 0; i < len; i++)
-					vector.push(this.readDouble());
-			}
-			this.rememberObject(vector);
-			return vector;
-		}
-		
-		private function readObjectValue(type:uint):Object {
-			var value:Object = null;
-			var u:uint;
-			
-			switch (type) {
-				case AMF3_STRING:
-					value = this.readString();
-					break;
-				case AMF3_OBJECT:
-					try {
-						value = this.readScriptObject();
-					} catch (e:Error) {
-						throw new Error("Failed to deserialize: " + e);
-					}
-					break;
-				case AMF3_ARRAY:
-					value = this.readArray();
-					break;
-				case AMF3_BOOLEAN_FALSE:
-					value = false;
-					break;
-				case AMF3_BOOLEAN_TRUE:
-					value = true;
-					break;
-				case AMF3_INTEGER:
-					u = this.readUInt29();
-					// Symmetric with writing an integer to fix sign bits for
-					// negative values...
-					value = (u << 3) >> 3;
-					break;
-				case AMF3_DOUBLE:
-					value = this.readDouble();
-					break;
-				case AMF3_UNDEFINED:
-				case AMF3_NULL:
-					break;
-				case AMF3_DATE:
-					value = this.readDate();
-					break;
-				case AMF3_BYTEARRAY:
-					value = this.readByteArray();
-					break;
-				case AMF3_VECTOR_INT:
-				case AMF3_VECTOR_UINT:
-				case AMF3_VECTOR_DOUBLE:
-				case AMF3_VECTOR_OBJECT:
-					value = this.readAmf3Vector(type);
-					break;
-				case AMF0_AMF3:
-					value = this.readObject();
-					break;
-				default:
-					throw new Error("Unsupported AMF type: " + type);
-			}
-			return value;
-		}
-		
-		public function readBoolean():Boolean {
-			return this.read() === 1;
-		}
-		
-		private function toVector(type:uint, array:Array, fixed:Boolean):Array {
-			// TODO (aharui) handle vectors
-			return array;
-		}
-		
-		//IDataOutput -------------------------------------------------------------------------------------
-		
-		public function writeBytes(bytes:AMFBinaryData, offset:uint = 0, length:uint = 0):void {
-			this.data = this.data.concat(bytes.data.slice(offset, offset + length));
-			pos += length;
-		}
-		
-		public function writeByte(value:int):void {
-			write(value & 255)
-		}
-		
-		//IDataInput -------------------------------------------------------------------------------------
-		
-		public function get bytesAvailable():uint {
-			return 0;
-		}
-		
-		public function readUnsignedByte():uint {
-			return 0;
-		}
-	}
-	
-}
-
-/**
- *  @royalesuppresspublicvarwarning
- */
-class Traits {
-	private static var _emtpy_object:Traits;
-	
-	public static function getDynObjectTraits(fields:Array):Traits {
-		var traits:Traits;
-		if (fields.length == 0) {
-			if (_emtpy_object) return _emtpy_object;
-			traits = _emtpy_object = new Traits();
-			traits.qName = 'Object';
-			traits.externalizable = false;
-			traits.dynamic = true;
-			return traits;
-		}
-		traits = new Traits();
-		traits.qName = 'Object';
-		traits.externalizable = false;
-		traits.dynamic = true;
-		traits.props = fields;
-		return traits;
-	}
-	
-	public var alias:String = '';
-	public var qName:String;
-	public var externalizable:Boolean;
-	public var dynamic:Boolean;
-	public var count:uint = 0;
-	public var props:Array = [];
-	public var nullValues:Object = {};
-	
-	public function hasProp(prop:String):Boolean {
-		return props.indexOf(prop) != -1;
-	}
-	
-	public function toString():String {
-		return 'Traits for \'' + qName + '\'\n'
-				+ 'alias: \'' + alias + '\'\n'
-				+ 'externalizable:' + Boolean(externalizable) + '\n'
-				+ 'dynamic:' + Boolean(dynamic) + '\n'
-				+ 'count:' + count + '\n'
-				+ 'props:\n\t' + props.join('\n\t');
-	}
-}
diff --git a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFNetConnection.as b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFNetConnection.as
index b730984..e845098 100644
--- a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFNetConnection.as
+++ b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFNetConnection.as
@@ -52,6 +52,12 @@ public class AMFNetConnection
     // Constructor
     //
     //--------------------------------------------------------------------------
+    
+    
+	private static const UNKNOWN_CONTENT_LENGTH:int = 1;
+	private static const AMF0_BOOLEAN:int = 1;
+	private static const NULL_STRING:String = "null";
+	private static const AMF0_AMF3:int = 17;
 
     /**
      *  Constructor
@@ -340,7 +346,7 @@ public class AMFNetConnection
                     var message:ActionMessage;
                     var body:MessageBody;
 	                _relinquishCall(call);
-                    var deserializer:AMFBinaryData = new AMFBinaryData(new Uint8Array(xhr.response) as Array);
+                    var deserializer:AMFBinaryData = new AMFBinaryData(xhr.response);
                     try
                     {
                         message = readMessage(deserializer) as ActionMessage;
@@ -409,10 +415,10 @@ public class AMFNetConnection
     {
         writer.writeUTF(header.name);
         writer.writeBoolean(header.mustUnderstand);
-        writer.writeInt(AMFBinaryData.UNKNOWN_CONTENT_LENGTH);
-        writer.reset();
+        writer.writeInt(UNKNOWN_CONTENT_LENGTH);
         //writer.writeObject(header.data);
-        writer.write(AMFBinaryData.AMF0_BOOLEAN);
+        trace('not sending header data:', header.data);
+        writer.writeByte(AMF0_BOOLEAN);
         writer.writeBoolean(true);
     }
 
@@ -420,18 +426,18 @@ public class AMFNetConnection
     private function writeBody(writer:AMFBinaryData, body:MessageBody):void
     {
         if (body.targetURI == null) {
-            writer.writeUTF(AMFBinaryData.NULL_STRING);
+            writer.writeUTF(NULL_STRING);
         } else {
             writer.writeUTF(body.targetURI);
         }
         if (body.responseURI == null) {
-            writer.writeUTF(AMFBinaryData.NULL_STRING);
+            writer.writeUTF(NULL_STRING);
         } else {
             writer.writeUTF(body.responseURI);
         }
-        writer.writeInt(AMFBinaryData.UNKNOWN_CONTENT_LENGTH);
-        writer.reset();
-        writer.write(AMFBinaryData.AMF0_AMF3);
+        writer.writeInt(UNKNOWN_CONTENT_LENGTH);
+ 
+        writer.writeByte(AMF0_AMF3);
         writer.writeObject(body.data);
 
     }
@@ -458,13 +464,16 @@ public class AMFNetConnection
         var header:MessageHeader = new MessageHeader();
         header.name = reader.readUTF();
         header.mustUnderstand = reader.readBoolean();
-        reader.pos += 4; //length
-        reader.reset();
-        var type:uint = reader.read();
+        //reader.pos += 4; //length
+        //reader.reset();
+		var len:uint = reader.readUnsignedInt();
+		trace('readHeader len',len);
+        var type:uint = reader.readUnsignedByte();
         if (type != 2) { //amf0 string
             throw "Only string header data supported.";
         }
         header.data = reader.readUTF();
+        trace('readHeader data:',header.data);
         return header;
     }
 
@@ -474,8 +483,10 @@ public class AMFNetConnection
         var body:MessageBody = new MessageBody();
         body.targetURI = reader.readUTF();
         body.responseURI = reader.readUTF();
-        reader.pos += 4; //length
-        reader.reset();
+        //reader.pos += 4; //length
+        var len:uint = reader.readUnsignedInt();
+        trace('readBody len',len);
+       //reader.reset();
         body.data = reader.readObject();
         return body;
     }
diff --git a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDataOutput.as b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDynamicPropertyOutput.as
similarity index 50%
rename from frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDataOutput.as
rename to frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDynamicPropertyOutput.as
index cb59c1a..349df35 100644
--- a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDataOutput.as
+++ b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDynamicPropertyOutput.as
@@ -18,18 +18,26 @@
 ////////////////////////////////////////////////////////////////////////////////
 package org.apache.royale.net.utils
 {
-    import org.apache.royale.net.remoting.amf.AMFBinaryData;
 
     /**
-     * initial work on replacement for flash.utils.IDataOutput
+     * This interface controls the serialization of dynamic properties of dynamic objects.
+     * You use this interface with the IDynamicPropertyWriter interface to create an implementation for
+     * configuring serialization of dynamic objects.
      */
-    public interface IDataOutput
+    public interface IDynamicPropertyOutput
     {
-        function writeBytes(bytes:AMFBinaryData, offset:uint = 0, length:uint = 0):void;
-
-        function writeByte(value:int):void;
-
-        function writeObject(object:*):void;
+	
+		/**
+         * Adds a dynamic property to the binary output of a serialized object.
+         * When the object is subsequently read (using a method such as readObject),
+         * it contains the new property. You can use this method to exclude properties
+         * of dynamic objects from serialization; to write values to properties
+         * of dynamic objects; or to create new properties for dynamic objects.
+         *
+		 * @param name  The name of the property. You can use this parameter either to specify the name of an existing property of the dynamic object or to create a new property.
+		 * @param value The value to write to the specified property.
+		 */
+		function writeDynamicProperty(name:String, value:*):void
     }
 
-}
\ No newline at end of file
+}
diff --git a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDataInput.as b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDynamicPropertyWriter.as
similarity index 50%
rename from frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDataInput.as
rename to frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDynamicPropertyWriter.as
index 1916c00..68830b4 100644
--- a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDataInput.as
+++ b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/utils/IDynamicPropertyWriter.as
@@ -18,17 +18,24 @@
 ////////////////////////////////////////////////////////////////////////////////
 package org.apache.royale.net.utils
 {
-    
+
     /**
-     * initial work on replacement for flash.utils.IDataInput
+     * This interface controls the serialization of dynamic properties of dynamic objects.
+	 * This interface is used with the IDynamicPropertyOutput interface to control the serialization
+	 * of dynamic properties of dynamic objects. To use this interface, assign an object that implements
+	 * the IDynamicPropertyWriter interface to the AMFObjectEncoding.dynamicPropertyWriter property.
      */
-    public interface IDataInput
+    public interface IDynamicPropertyWriter
     {
-        function get bytesAvailable():uint;
-
-        function readUnsignedByte():uint;
-
-        function readObject():*;
+	
+		/**
+         * Writes the name and value of an IDynamicPropertyOutput object to an object with dynamic properties.
+		 * If ObjectEncoding.dynamicPropertyWriter is set, this method is invoked for each object with dynamic properties.
+         *
+		 * @param name  The name of the property. You can use this parameter either to specify the name of an existing property of the dynamic object or to create a new property.
+		 * @param value The value to write to the specified property.
+		 */
+		function writeDynamicProperties(obj:Object, output:IDynamicPropertyOutput):void
     }
 
 }
diff --git a/pom.xml b/pom.xml
index 21c0c95..cfd62a8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -144,7 +144,7 @@
           <artifactId>versions-maven-plugin</artifactId>
           <version>2.7</version>
         </plugin>
-        
+
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>build-helper-maven-plugin</artifactId>
@@ -240,6 +240,8 @@
                 target directories. We don't want that.
             -->
             <exclude>**/target/**</exclude>
+
+            <exclude>**/src/test/royale/out/**</exclude>
           </excludes>
         </configuration>
         <dependencies>