Added AMFStorage
diff --git a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/models/TodoModel.as b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/models/TodoModel.as
index 85c630b..ed21421 100644
--- a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/models/TodoModel.as
+++ b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/models/TodoModel.as
@@ -26,7 +26,7 @@
 	import org.apache.royale.core.IStrand;
 	import org.apache.royale.events.EventDispatcher;
 	import org.apache.royale.routing.Router;
-	import org.apache.royale.storage.LocalStorage;
+	import org.apache.royale.storage.AMFStorage;
 
 	[Bindable]
     /**
@@ -72,30 +72,18 @@
          */
         public function setItemStore(items:Array):void
         {
-            var itemStr:String = JSON.stringify(items);
-            storage.setItem("todomvc",itemStr);
+            storage.data["items"] = items;
+            storage.save();
         }
         public function getItemStore():Array
         {
-            var itemArr:Array = [];
-            var itemStr:String = storage.getItem("todomvc") as String;
-            if(itemStr)
-            {
-                try{
-                    itemArr = JSON.parse(itemStr) as Array;
-                    for(var i:int=0;i<itemArr.length;i++){
-                        itemArr[i] = TodoVO.fromJSON(itemArr[i]);
-                    }
-                }catch(err:Error){
-                    return [];
-                }
-            }
+            var itemArr:Array = storage.data["items"] || [];
             return itemArr;
         }
         /**
          *  Local storage for the todo items
          */
-        private var storage:LocalStorage = new LocalStorage();// SharedObject.getLocal("todomvc");
+        private var storage:AMFStorage = AMFStorage.getLocal("todomvc");
 
         /**
          * the list of items binded to the todo list component
diff --git a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/vos/TodoVO.as b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/vos/TodoVO.as
index 8fb4ee7..d6ba6db 100644
--- a/examples/jewel/todomvc/src/main/royale/jewel/todomvc/vos/TodoVO.as
+++ b/examples/jewel/todomvc/src/main/royale/jewel/todomvc/vos/TodoVO.as
@@ -43,7 +43,11 @@
         {
             this.label = label;
         }
-
+        
+        /**
+         * The following two methods could be used if we were saving and reading the data as JSON,
+         * but we're actually saving and reading as AMF, so they are not necessary.
+         */
         public function toJSON():Object{
             return {
                 "label":label,
diff --git a/frameworks/build.xml b/frameworks/build.xml
index 4020d38..db5eaba 100644
--- a/frameworks/build.xml
+++ b/frameworks/build.xml
@@ -131,9 +131,9 @@
         <antcall target="JQuery"/>
         <antcall target="Mobile"/>
 
+        <antcall target="Network"/>
         <antcall target="Storage"/>
         <antcall target="XML"/>
-        <antcall target="Network"/>
         <antcall target="Text"/>
         <antcall target="TLF"/>
 		<antcall target="MaterialDesignLite"/>
diff --git a/frameworks/js/projects/StorageJS/src/main/config/compile-js-config.xml b/frameworks/js/projects/StorageJS/src/main/config/compile-js-config.xml
index dc0c90c..a149ae3 100644
--- a/frameworks/js/projects/StorageJS/src/main/config/compile-js-config.xml
+++ b/frameworks/js/projects/StorageJS/src/main/config/compile-js-config.xml
@@ -58,6 +58,8 @@
             <path-element>../../../../../../../js/libs/cordova.swc</path-element>
             <path-element>../../../../../libs/LanguageJS.swc</path-element>
             <path-element>../../../../../libs/CoreJS.swc</path-element>
+            <path-element>../../../../../libs/NetworkJS.swc</path-element>
+            <path-element>../../../../../libs/ReflectionJS.swc</path-element>
         </external-library-path>
         
         <namespaces>
@@ -72,6 +74,7 @@
         </source-path>
         
         <warn-no-constructor>false</warn-no-constructor>
+        <allow-abstract-classes>true</allow-abstract-classes>
     </compiler>
     
     <include-file>
diff --git a/frameworks/projects/Storage/src/main/config/compile-swf-config.xml b/frameworks/projects/Storage/src/main/config/compile-swf-config.xml
index 0d9a221..6eccbe5 100644
--- a/frameworks/projects/Storage/src/main/config/compile-swf-config.xml
+++ b/frameworks/projects/Storage/src/main/config/compile-swf-config.xml
@@ -31,6 +31,8 @@
         <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>
+            <path-element>../../../../../libs/Reflection.swc</path-element>
         </external-library-path>
         
 		<mxml>
@@ -73,6 +75,7 @@
         </source-path>
         
         <warn-no-constructor>false</warn-no-constructor>
+        <allow-abstract-classes>true</allow-abstract-classes>
     </compiler>
     
     <include-file>
diff --git a/frameworks/projects/Storage/src/main/resources/basic-manifest.xml b/frameworks/projects/Storage/src/main/resources/basic-manifest.xml
index 00a7a5a..b2dcd21 100644
--- a/frameworks/projects/Storage/src/main/resources/basic-manifest.xml
+++ b/frameworks/projects/Storage/src/main/resources/basic-manifest.xml
@@ -20,6 +20,7 @@
 
 
 <componentPackage>
+	<component id="AMFStorage" class="org.apache.royale.storage.AMFStorage"/>
 	<component id="LocalStorage" class="org.apache.royale.storage.LocalStorage"/>
 	<component id="PermanentStorage" class="org.apache.royale.storage.PermanentStorage"/>
 </componentPackage>
diff --git a/frameworks/projects/Storage/src/main/royale/StorageClasses.as b/frameworks/projects/Storage/src/main/royale/StorageClasses.as
index 3955508..3ee52fb 100644
--- a/frameworks/projects/Storage/src/main/royale/StorageClasses.as
+++ b/frameworks/projects/Storage/src/main/royale/StorageClasses.as
@@ -27,6 +27,7 @@
  */
 internal class StorageClasses
 {
+	import org.apache.royale.storage.AMFStorage; AMFStorage;
     import org.apache.royale.storage.LocalStorage; LocalStorage;
     import org.apache.royale.storage.providers.LocalStorageProvider; LocalStorageProvider;
 
diff --git a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/AMFStorage.as b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/AMFStorage.as
new file mode 100644
index 0000000..c766894
--- /dev/null
+++ b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/AMFStorage.as
@@ -0,0 +1,208 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//	Licensed to the Apache Software Foundation (ASF) under one or more
+//	contributor license agreements.	See the NOTICE file distributed with
+//	this work for additional information regarding copyright ownership.
+//	The ASF licenses this file to You under the Apache License, Version 2.0
+//	(the "License"); you may not use this file except in compliance with
+//	the License.	You may obtain a copy of the License at
+//
+//			http://www.apache.org/licenses/LICENSE-2.0
+//
+//	Unless required by applicable law or agreed to in writing, software
+//	distributed under the License is distributed on an "AS IS" BASIS,
+//	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//	See the License for the specific language governing permissions and
+//	limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.royale.storage
+{
+	COMPILE::SWF{
+		import flash.events.Event;
+		import flash.net.SharedObject;
+	}
+
+	COMPILE::JS
+	{
+		import goog.DEBUG;
+		import org.apache.royale.debugging.assert;
+		import org.apache.royale.net.remoting.amf.AMFBinaryData;
+	}
+
+	import org.apache.royale.events.EventDispatcher;
+
+	public class AMFStorage extends EventDispatcher
+	{
+		private static const map:Object = {};
+
+    public static const PENDING:String = "pending";
+    public static const FLUSHED:String = "flushed";
+    public static const FAILED:String = "failed";
+
+		public static function getLocal(name:String, localPath:String = null, secure:Boolean = false):AMFStorage
+		{
+			var pathKey:String = localPath == null ? '$null$' : localPath;
+			COMPILE::JS {
+					localPath = pathKey;
+			}
+			var cached:AMFStorage = map[pathKey + '::' + name];
+			if (!cached)
+			{
+				cached = new AMFStorage();
+				map[pathKey + '::' + name] = cached;
+				cached.setName(name);
+				cached.setLocalPath(localPath);
+				cached.createSO(secure);
+			}
+			COMPILE::JS{
+				if (!map['#']) {
+					window.addEventListener('pagehide', unloadHandler);
+					map['#'] = true;
+				}
+			}
+			return cached;
+		}	
+		COMPILE::JS
+		private static function unloadHandler(event:PageTransitionEvent):void{
+				//@todo consider whether we do anything different if event.persisted is true or false
+				for (var key:String in map) {
+						if (key != '#') {
+								var so:AMFStorage = map[key];
+								//@todo what to do with errors here:
+								so.save();
+						}
+				}
+		}
+
+		private function AMFStorage()
+		{
+			
+		}
+		COMPILE::SWF
+		private var _so:flash.net.SharedObject;
+		
+		COMPILE::JS
+		private var _ls:Storage;
+
+		/**
+		 *
+		 * @param minDiskSpace ignored for javascript targets
+		 * @return a string indicating the flush status. This can be (on swf) FLUSHED or PENDING on swf. For JS is it FLUSHED or FAILED
+		 *
+		 * @throws Error #2044: Unhandled NetStatusEvent
+		 */
+		public function save(minDiskSpace:int = 0):String
+		{
+			COMPILE::JS
+			{
+				if (_data)
+				{
+					try{
+						var amf:AMFBinaryData = new AMFBinaryData();
+						amf.writeObject(_data);
+						var base64:String = window['btoa'](String.fromCharCode.apply(null, amf.array));
+						_ls.setItem(_localPath + "::" + _name, base64);
+					} catch(e:Error) {
+						return FAILED;
+					}
+				}
+				//js never returns pending, because there is no way for the user to accept or decline the byte size storage limits
+				return FLUSHED;
+			}
+			COMPILE::SWF
+			{
+					return _so.flush(minDiskSpace);
+			}
+		}
+
+		public function clear():void{
+			COMPILE::SWF{
+				_so.clear();
+			}
+			COMPILE::JS{
+				if (_data) {
+					if (_ls) {
+						_ls.removeItem(_localPath + "::" + _name);
+					}
+					_data = null;
+				}
+			}
+		}
+		
+		COMPILE::JS
+		private var _data:Object;
+
+		public function get data():Object
+		{
+			COMPILE::SWF
+			{
+				return _so.data;
+			}
+			COMPILE::JS
+			{
+				if (!_data)
+				{
+					_data = {};
+				}
+				return _data;
+			}
+		}
+		
+		private var _name:String;
+		protected function setName(name:String):void
+		{
+			_name = name;
+		}
+		
+		private var _localPath:String;
+		private function setLocalPath(localPath:String):void
+		{
+			_localPath = localPath;
+		}
+		COMPILE::SWF
+		protected function redispatch(event:flash.events.Event):void{
+			//just redispatch?
+			dispatchEvent(event.clone());
+		}
+        
+		private function createSO(secure:Boolean):void
+		{
+			COMPILE::SWF{
+				_so = flash.net.SharedObject.getLocal(_name, _localPath, secure);
+				_so.addEventListener('netStatus', redispatch);
+				_so.addEventListener('asyncError', redispatch); //not sure about this one for LSO..
+				//_so.addEventListener('sync', redispatch); //only relevant for RSO, not LSO
+			}
+			COMPILE::JS{
+				_ls = window.localStorage;
+				if(goog.DEBUG)
+				{
+					if (!_ls && typeof Storage != "undefined") {
+						//this gets around an issue with local testing with file:// protocol in IE11
+						var p:String = window.location.pathname.replace(/(^..)(:)/, "$1$$");
+						window.location.href = window.location.protocol + "//127.0.0.1" + p;
+						_ls = window.localStorage;
+					}
+				}
+				assert(_ls != null,'local storage not supported');
+				var base64:String = _ls.getItem(_localPath + "::" + _name);
+				if (base64)
+				{
+					var binary_string:String = window['atob'](base64);
+					var arr:Uint8Array = new Uint8Array(
+						binary_string.split('')
+							.map(
+								function (charStr:String):uint
+								{
+									return charStr.charCodeAt(0);
+								}
+							)
+					);
+					var amf:AMFBinaryData = new AMFBinaryData(arr.buffer);
+					_data = amf.readObject();
+				}
+			}
+		}
+	}
+}
\ No newline at end of file