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

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

commit bab0a204c68831522523df105c7c3da1f0e7a188
Author: Alex Harui <[email protected]>
AuthorDate: Mon Sep 30 11:03:32 2019 -0700

    beginnings of implementation of WebService
---
 .../MXRoyale/src/main/royale/MXRoyaleClasses.as    |    1 +
 .../royale/mx/messaging/channels/HTTPChannel.as    | 1268 ++++++++++++++++++++
 .../mx/messaging/channels/SecureHTTPChannel.as     |   80 ++
 .../mx/messaging/channels/amfx/AMFXContext.as      |  304 +++++
 .../mx/messaging/channels/amfx/AMFXDecoder.as      |  638 ++++++++++
 .../mx/messaging/channels/amfx/AMFXEncoder.as      |  510 ++++++++
 .../mx/messaging/channels/amfx/AMFXHeader.as       |   45 +
 .../mx/messaging/channels/amfx/AMFXResult.as       |   41 +
 .../royale/mx/messaging/config/ServerConfig.as     |   28 +-
 .../MXRoyale/src/main/royale/mx/net/URLLoader.as   |    5 +
 .../src/main/royale/mx/rpc/soap/LoadEvent.as       |    6 +-
 .../src/main/royale/mx/rpc/soap/Operation.as       |   71 +-
 .../src/main/royale/mx/rpc/soap/SOAPDecoder.as     |   29 +-
 .../src/main/royale/mx/rpc/soap/SOAPEncoder.as     |    8 +-
 .../src/main/royale/mx/rpc/soap/SOAPFault.as       |    1 -
 .../src/main/royale/mx/rpc/soap/WebService.as      |   43 +-
 .../src/main/royale/mx/rpc/soap/mxml/Operation.as  |    2 +-
 .../src/main/royale/mx/rpc/soap/mxml/WebService.as |   29 +-
 .../MXRoyale/src/main/royale/mx/rpc/wsdl/WSDL.as   |    2 +-
 .../src/main/royale/mx/rpc/wsdl/WSDLLoader.as      |    2 +-
 20 files changed, 3046 insertions(+), 67 deletions(-)

diff --git a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as 
b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
index 9619309..3c14ebe 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
@@ -198,6 +198,7 @@ internal class MXRoyaleClasses
        import mx.rpc.http.HTTPMultiService; HTTPMultiService;
        import mx.messaging.messages.HTTPRequestMessage; HTTPRequestMessage;
        import mx.messaging.channels.DirectHTTPChannel; DirectHTTPChannel;
+    import mx.messaging.channels.HTTPChannel; HTTPChannel;
        import mx.messaging.errors.MessageSerializationError; 
MessageSerializationError;
        import mx.rpc.http.SerializationFilter; SerializationFilter;
        import mx.rpc.http.AbstractOperation; AbstractOperation;
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/HTTPChannel.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/HTTPChannel.as
new file mode 100644
index 0000000..e520f07
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/HTTPChannel.as
@@ -0,0 +1,1268 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.messaging.channels
+{
+
+import mx.events.ErrorEvent;
+import org.apache.royale.events.Event;
+import mx.events.IOErrorEvent;
+import mx.events.SecurityErrorEvent;
+import mx.net.URLLoader;
+import org.apache.royale.net.URLRequest;
+
+import mx.core.mx_internal;
+import mx.messaging.RoyaleClient;
+import mx.messaging.MessageAgent;
+import mx.messaging.MessageResponder;
+import mx.messaging.channels.amfx.AMFXDecoder;
+import mx.messaging.channels.amfx.AMFXEncoder;
+import mx.messaging.channels.amfx.AMFXHeader;
+import mx.messaging.channels.amfx.AMFXResult;
+import mx.messaging.config.ConfigMap;
+import mx.messaging.config.LoaderConfig;
+import mx.messaging.config.ServerConfig;
+import mx.messaging.errors.MessageSerializationError;
+import mx.messaging.events.ChannelFaultEvent;
+import mx.messaging.messages.AbstractMessage;
+import mx.messaging.messages.AcknowledgeMessage;
+import mx.messaging.messages.AsyncMessage;
+import mx.messaging.messages.CommandMessage;
+import mx.messaging.messages.ErrorMessage;
+import mx.messaging.messages.HTTPRequestMessage;
+import mx.messaging.messages.IMessage;
+import mx.messaging.messages.MessagePerformanceInfo;
+import mx.messaging.messages.MessagePerformanceUtils;
+import mx.netmon.NetworkMonitor;
+import mx.utils.ObjectUtil;
+import mx.utils.StringUtil;
+
+use namespace mx_internal;
+
+/**
+ *  The HTTPChannel class provides the HTTP support for messaging.
+ *  You can configure this Channel to poll the server at an interval
+ *  to approximate server push.
+ *  You can also use this Channel with polling disabled to send RPC messages
+ *  to remote destinations to invoke their methods.
+ *
+ *  <p>
+ *  The HTTPChannel relies on network services native to Flash Player and AIR,
+ *  and exposed to ActionScript by the URLLoader class.
+ *  This channel uses URLLoader exclusively, and creates a new URLLoader
+ *  per request.
+ *  </p>
+ *
+ *  <p>
+ *  Channels are created within the framework using the
+ *  <code>ServerConfig.getChannel()</code> method. Channels can be constructed
+ *  directly and assigned to a ChannelSet if desired.
+ *  </p>
+ *
+ *  <p>
+ *  Channels represent a physical connection to a remote endpoint.
+ *  Channels are shared across destinations by default.
+ *  This means that a client targetting different destinations may use
+ *  the same Channel to communicate with these destinations.
+ *  </p>
+ *
+ *  <p>
+ *  When used in polling mode, this Channel polls the server for new messages
+ *  based on the <code>polling-interval-seconds</code> property in the 
configuration file,
+ *  and this can be changed by setting the <code>pollingInterval</code> 
property.
+ *  The default value is 3 seconds.
+ *  To enable polling, the channel must be connected and the 
<code>polling-enabled</code>
+ *  property in the configuration file must be set to <code>true</code>, or the
+ *  <code>pollingEnabled</code> property of the Channel must be set to 
<code>true</code>.
+ *  </p>
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion BlazeDS 4
+ *  @productversion LCDS 3 
+ */
+public class HTTPChannel extends PollingChannel
+{
+    
//--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     *
+     *  @param id The id of this Channel.
+     *  @param uri The uri for this Channel.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function HTTPChannel(id:String = null, uri:String = null)
+    {
+        super(id, uri);
+
+        _encoder = new AMFXEncoder();
+        _appendToURL = "";
+        _messageQueue = [];
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Variables
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private var _appendToURL:String;
+
+    /**
+     *  @private
+     *  The loader used to ping the server in internalConnect. We need to hang 
onto a reference
+     *  in order to time out a connect attempt.
+     */
+    private var _connectLoader:ChannelRequestLoader;
+
+    /**
+     *  @private
+     */
+    private var _encoder:AMFXEncoder;
+
+    /**
+     *  @private
+     *  Records the request that needs to be completed before other
+     *  requests can be sent.
+     */
+    private var _pendingRequest:ChannelRequestLoader = null;
+
+    /**
+     *  @private
+     *  This queue contains the messages from send requests that
+     *  occurred while an authentication attempt is underway.
+     */
+    private var _messageQueue:Array;
+
+    
//--------------------------------------------------------------------------
+    //
+    // Properties
+    //
+    
//--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  polling
+    //----------------------------------
+
+    /**
+     *  Reports whether the channel is actively polling.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function get polling():Boolean
+    {
+        return pollOutstanding;
+    }
+
+    //----------------------------------
+    //  piggybackingEnabled
+    //----------------------------------
+
+    /**
+     *  Indicates whether this channel will piggyback poll requests along
+     *  with regular outbound messages when an outstanding poll is not in
+     *  progress. This allows the server to piggyback data for the client
+     *  along with its response to client's message.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function get piggybackingEnabled():Boolean
+    {
+        return internalPiggybackingEnabled;
+    }
+
+    /**
+     *  @private
+     */
+    public function set piggybackingEnabled(value:Boolean):void
+    {
+        internalPiggybackingEnabled = value;
+    }
+
+    //----------------------------------
+    //  pollingEnabled
+    //----------------------------------
+
+    /**
+     *  Indicates whether this channel is enabled to poll.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function get pollingEnabled():Boolean
+    {
+        return internalPollingEnabled;
+    }
+
+    /**
+     *  @private
+     */
+    public function set pollingEnabled(value:Boolean):void
+    {
+        internalPollingEnabled = value;
+    }
+
+    //----------------------------------
+    //  pollingInterval
+    //----------------------------------
+
+    /**
+     *  Provides access to the polling interval for this Channel.
+     *  The value is in milliseconds.
+     *  This value determines how often this Channel requests messages from
+     *  the server, to approximate server push.
+     *
+     *  @throws ArgumentError If the pollingInterval is assigned a value of 0 
or
+     *                        less.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function get pollingInterval():Number
+    {
+        return internalPollingInterval;
+    }
+
+    /**
+     *  @private
+     */
+    public function set pollingInterval(value:Number):void
+    {
+        internalPollingInterval = value;
+    }
+
+    //----------------------------------
+    //  protocol
+    //----------------------------------
+
+    /**
+     *  Returns the protocol for this channel (http).
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    override public function get protocol():String
+    {
+        return "http";
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Internal Properties
+    //
+    
//--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  appendToURL
+    //----------------------------------
+
+    /**
+     * @private
+     */
+    mx_internal function get appendToURL():String
+    {
+        return _appendToURL;
+    }
+
+    /**
+     *  @private
+     */
+    mx_internal function set appendToURL(value:String):void
+    {
+        if (value && endpoint)
+        {
+            _appendToURL = value;
+       }
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Overridden Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Processes polling related configuration settings.
+     */
+    override public function applySettings(settings:XML):void
+    {
+        super.applySettings(settings);
+        applyPollingSettings(settings);
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Overridden Protected Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    override protected function connectTimeoutHandler(event:Event):void
+    {
+        _connectLoader.close();
+        super.connectTimeoutHandler(event);
+    }
+
+    /**
+     *  @private
+     */
+    override protected function getDefaultMessageResponder(agent:MessageAgent, 
msg:IMessage):MessageResponder
+    {
+        return new HTTPMessageResponder(agent, msg, this);
+    }
+
+    /**
+     *  @private
+     *  Attempts to connect to the remote destination with the current endpoint
+     *  specified for this channel.
+     *  This will determine if a connection can be established.
+     */
+    override protected function internalConnect():void
+    {
+        // Ping the server to make sure that it is reachable.
+        var msg:CommandMessage = new CommandMessage();
+        if (credentials != null)
+        {
+            msg.operation = CommandMessage.LOGIN_OPERATION;
+            msg.body = credentials;
+        }
+        else
+        {
+            msg.operation = CommandMessage.CLIENT_PING_OPERATION;
+        }
+
+        // Report the messaging version for this Channel.
+        // msg.headers[CommandMessage.MESSAGING_VERSION] = messagingVersion;
+
+        // Indicate if requesting the dynamic configuration from the server.
+        if (ServerConfig.needsConfig(this))
+            msg.headers[CommandMessage.NEEDS_CONFIG_HEADER] = true;
+
+        // Add the FlexClient id header.
+        setRoyaleClientIdOnMessage(msg);
+
+        var urlRequest:URLRequest = createURLRequest(msg);
+        _connectLoader = new ChannelRequestLoader();
+        _connectLoader.setErrorCallbacks(pingErrorHandler);
+        _connectLoader.completeCallback = pingCompleteHandler;
+        _connectLoader.load(urlRequest);
+    }
+
+    /**
+     *  @private
+     *  Disconnects from the remote destination.
+     */
+    override protected function internalDisconnect(rejected:Boolean = 
false):void
+    {
+        // Attempt to notify the server of the disconnect.
+        if (!rejected && !shouldBeConnected)
+        {
+            var msg:CommandMessage = new CommandMessage();
+            msg.operation = CommandMessage.DISCONNECT_OPERATION;
+            internalSend(new MessageResponder(null, msg, null));
+        }
+        // Shutdown locally.
+        setConnected(false);
+        super.internalDisconnect(rejected);
+        disconnectSuccess(rejected); // make sure to notify everyone that we 
have disconnected.
+    }
+
+    /**
+     *  @private
+     */
+    override protected function internalSend(msgResp:MessageResponder):void
+    {
+        if (_pendingRequest != null)
+        {
+            _messageQueue.push(msgResp);
+        }
+        else
+        {
+            // Set the global FlexClient Id.
+            setRoyaleClientIdOnMessage(msgResp.message);
+
+            try
+            {
+                // If MPI is enabled initialize MPI object and stamp it with 
client send time
+                if (mpiEnabled)
+                {
+                    var mpii:MessagePerformanceInfo = new 
MessagePerformanceInfo();
+                    if (recordMessageTimes)
+                        mpii.sendTime = new Date().getTime();
+                    
msgResp.message.headers[MessagePerformanceUtils.MPI_HEADER_IN] = mpii;
+                }
+
+                // Finally, if "Small Messages" are enabled, send this form 
instead of
+                // the normal message where possible.
+                /*
+                if (useSmallMessages && msgResp.message is ISmallMessage)
+                {
+                    var smallMessage:IMessage = 
ISmallMessage(msgResp.message).getSmallMessage();
+                    if (smallMessage != null)
+                        msgResp.message = smallMessage;
+                }
+                */
+
+                var urlLoader:ChannelRequestLoader;
+                var urlRequest:URLRequest = createURLRequest(msgResp.message);
+                if (msgResp is HTTPMessageResponder)
+                {
+                    var httpMsgResp:HTTPMessageResponder =
+                        HTTPMessageResponder(msgResp);
+                    urlLoader = httpMsgResp.urlLoader;
+                    urlLoader.completeCallback = httpMsgResp.completeHandler;
+                    urlLoader.errorCallback = httpMsgResp.errorHandler;
+                    urlLoader.ioErrorCallback = httpMsgResp.ioErrorHandler;
+                    urlLoader.securityErrorCallback =
+                        httpMsgResp.securityErrorHandler;
+                }
+                else
+                {
+                    var responderWrapper:HTTPWrapperResponder =
+                        new HTTPWrapperResponder(msgResp);
+                    urlLoader = new ChannelRequestLoader();
+                    urlLoader.completeCallback =
+                        responderWrapper.completeHandler;
+                    urlLoader.setErrorCallbacks(responderWrapper.errorHandler);
+                }
+                urlLoader.requestProcessedCallback = requestProcessedHandler;
+
+                // Do not consider poll requests as pending requests to allow
+                // clients to send messages while waiting for poll response.
+                if (!(msgResp.message is CommandMessage && 
CommandMessage(msgResp.message).operation == CommandMessage.POLL_OPERATION))
+                    _pendingRequest = urlLoader;
+
+                urlLoader.load(urlRequest);
+            }
+            catch(e:MessageSerializationError)
+            {
+                msgResp.agent.fault(e.fault, msgResp.message);
+            }
+        }
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Internal Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Utility function to handle a connection related ErrorMessage.
+     *
+     *  @param msg The ErrorMessage returned during a connect attempt.
+     */
+    mx_internal function connectionError(msg:ErrorMessage):void
+    {
+        var faultEvent:ChannelFaultEvent = ChannelFaultEvent.createEvent(this, 
false,
+                "Channel.Connect.Failed", "error", msg.faultDetail + " url: '" 
+ endpoint +
+                    (_appendToURL != null ? _appendToURL : "") + "'");
+        faultEvent.rootCause = msg;
+        connectFailed(faultEvent);
+    }
+
+    /**
+     *  @private
+     *  This method will serialize the specified message into a new instance of
+     *  a URLRequest and return it.
+     *
+     *  @param   message Message to serialize
+     *  @return  URLRequest
+     */
+    mx_internal function createURLRequest(message:IMessage):URLRequest
+    {
+        var result:URLRequest = new URLRequest();
+        if (_appendToURL)
+            result.url = endpoint + _appendToURL;
+        else
+            result.url = endpoint;
+        
+        // Propagate our requestTimeout for those platforms
+        // supporting the idleTimeout property on URLRequest.
+        if ("idleTimeout" in result && requestTimeout > 0)
+            result["idleTimeout"] = requestTimeout * 1000;
+                
+        monitorRpcMessage(message, result); 
+        
+        result.contentType = HTTPRequestMessage.CONTENT_TYPE_XML;
+
+        var packet:XML = _encoder.encode(message, null);
+        result.data = packet.toString();
+        result.method = "POST";
+        
+        return result;
+    }
+       
+       /**
+        * change the result url to redirect request to Network Monitor
+        */
+       
+       private function monitorRpcMessage(message:IMessage, 
result:URLRequest):void
+       {
+               if (NetworkMonitor.isMonitoring())
+               {               
+                       var redirectedUrl:String = 
NetworkMonitor.adjustNetConnectionURL(LoaderConfig.url, result.url);
+                       if(redirectedUrl != null){                              
+                               result.url = redirectedUrl;
+                       }               
+               }
+       }
+       
+    
//--------------------------------------------------------------------------
+    //
+    // Protected Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     * @private
+     */
+    protected function internalPingComplete(msg:AsyncMessage):void
+    {
+        if (msg != null)
+        {
+            ServerConfig.updateServerConfigData(msg.body as ConfigMap, 
endpoint);
+
+            // Set the server assigned FlexClient Id.
+            if (RoyaleClient.getInstance().id == null && 
msg.headers[AbstractMessage.FLEX_CLIENT_ID_HEADER] != null)
+                RoyaleClient.getInstance().id = 
msg.headers[AbstractMessage.FLEX_CLIENT_ID_HEADER];
+        }
+
+        // Process the features advertised by the server endpoint.
+        /*
+        if (msg.headers[CommandMessage.MESSAGING_VERSION] != null)
+        {
+            var serverVersion:Number = 
msg.headers[CommandMessage.MESSAGING_VERSION] as Number;
+            handleServerMessagingVersion(serverVersion);
+        }
+        */
+
+        connectSuccess();
+        if (credentials != null && !(msg is ErrorMessage))
+            setAuthenticated(true);
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Private Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Special handler for AMFX packet level header "AppendToGatewayUrl".
+     *  When we receive this header we assume the server detected that a 
session
+     *  was created but it believed the client could not accept its session
+     *  cookie, so we need to decorate the channel endpoint with the session 
id.
+     *
+     *  We do not modify the underlying endpoint property, however, as this
+     *  session is transient and should not apply if the channel is 
disconnected
+     *  and re-connected at some point in the future.
+     */
+    private function AppendToGatewayUrl(value:String):void
+    {
+        if (value != null)
+            appendToURL = value;
+    }
+
+    private function decodePacket(event:Event):AMFXResult
+    {
+        var raw:String = String(URLLoader(event.target).data);
+        var xmlData:XML = new XML(raw);
+        var _decoder:AMFXDecoder = new AMFXDecoder();
+        var packet:AMFXResult = _decoder.decode(xmlData);
+        return packet;
+    }
+
+    /**
+     *  @private
+     *  Attempts to replicate the packet-level header functionality that 
AMFChannel
+     *  uses for response headers such as AppendToGatewayUrl for session id 
tracking.
+     */
+    private function processHeaders(packet:AMFXResult):void
+    {
+        if (packet.headers != null)
+        {
+            try
+            {
+                for (var i:uint = 0; i < packet.headers.length; i++)
+                {
+                    var header:AMFXHeader = packet.headers[i];
+                    if (header != null && header.name == APPEND_TO_URL_HEADER)
+                    {
+                        AppendToGatewayUrl(String(header.content));
+                    }
+                }
+            }
+            catch(e:Error)
+            {
+            }
+        }
+    }
+
+    /**
+     *  @private
+     *  This method indicates that we successfully connected to the endpoint.
+     *  Called as a result of the ping operation performed in the
+     *  internalConnect() method.
+     */
+    private function pingCompleteHandler(event:Event):void
+    {
+        var packet:AMFXResult = decodePacket(event);
+        processHeaders(packet);
+        var msg:AsyncMessage = packet.result as AsyncMessage;
+        if (msg != null && (msg is ErrorMessage) &&
+            ErrorMessage(msg).faultCode == "Client.Authentication")
+        {
+            internalPingComplete(msg);
+            var faultEvent:ChannelFaultEvent = 
ChannelFaultEvent.createEvent(this, false, "Channel.Authentication.Error", 
"warn");
+            faultEvent.rootCause = ErrorMessage(msg);
+            dispatchEvent(faultEvent);
+        }
+        else
+        {
+            internalPingComplete(msg);
+        }
+    }
+
+    /**
+     *  @private
+     *  This method dispatches the appropriate error to any message agents, and
+     *  is called as a result of the ping operation performed in the
+     *  internalConnect() method.
+     */
+    private function pingErrorHandler(event:Event):void
+    {
+        _log.debug("'{0}' fault handler called. {1}", id, event.toString());
+        var faultEvent:ChannelFaultEvent = ChannelFaultEvent.createEvent(this, 
false,
+                                                    "Channel.Ping.Failed",
+                                                    "error",
+                                                    " url: '" + endpoint +
+                                                    (_appendToURL == null ? "" 
: _appendToURL + "'") + "'");
+        faultEvent.rootCause = event;
+        connectFailed(faultEvent);
+    }
+
+    /**
+     *  @private
+     *  Chains sends for pending messages.
+     */
+    private function requestProcessedHandler
+        (loader:ChannelRequestLoader, event:Event):void
+    {
+        if (_pendingRequest == loader)
+        {
+            _pendingRequest = null;
+        }
+        // TODO: we should do these in a batch for more efficiency and
+        // better session maintenance
+        while ((_messageQueue.length > 0) && (_pendingRequest == null))
+        {
+            internalSend(MessageResponder(_messageQueue.shift()));
+        }
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Static Constants
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private static const APPEND_TO_URL_HEADER:String = "AppendToGatewayUrl";
+}
+}
+
+//------------------------------------------------------------------------------
+//
+// Private Classes
+//
+//------------------------------------------------------------------------------
+
+import mx.events.ErrorEvent;
+import org.apache.royale.events.Event;
+import mx.events.IOErrorEvent;
+import mx.events.SecurityErrorEvent;
+import mx.net.URLLoader;
+import org.apache.royale.net.URLRequest;
+import mx.core.mx_internal;
+import mx.messaging.MessageAgent;
+import mx.messaging.MessageResponder;
+import mx.messaging.channels.HTTPChannel;
+import mx.messaging.channels.amfx.AMFXDecoder;
+import mx.messaging.channels.amfx.AMFXHeader;
+import mx.messaging.channels.amfx.AMFXResult;
+import mx.messaging.messages.AcknowledgeMessage;
+import mx.messaging.messages.AsyncMessage;
+import mx.messaging.messages.CommandMessage;
+import mx.messaging.messages.ErrorMessage;
+import mx.messaging.messages.HTTPRequestMessage;
+import mx.messaging.messages.IMessage;
+import mx.resources.IResourceManager;
+import mx.resources.ResourceManager;
+import mx.utils.StringUtil;
+
+use namespace mx_internal;
+
+[ResourceBundle("messaging")]
+
+/**
+ *  @private
+ *  This responder wraps another MessageResponder with HTTP functionality.
+ */
+class HTTPWrapperResponder
+{
+    
//--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Constructs a HTTPWrappedResponder.
+     *
+     *  @param wrappedResponder The responder to wrap.
+     */
+    public function HTTPWrapperResponder(wrappedResponder:MessageResponder)
+    {
+        super();
+        _wrappedResponder = wrappedResponder;
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Variables
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private var _wrappedResponder:MessageResponder;
+
+
+    /**
+     * @private
+     */
+    private var resourceManager:IResourceManager =
+                                    ResourceManager.getInstance();
+
+    
//--------------------------------------------------------------------------
+    //
+    // Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Handles a result returned from the remote destination.
+     *
+     *  @param event The completion event from the associated URLLoader.
+     */
+    public function completeHandler(event:Event):void
+    {
+        var raw:String = String(URLLoader(event.target).data);
+        var xmlData:XML = new XML(raw);
+        var _decoder:AMFXDecoder = new AMFXDecoder();
+        var packet:AMFXResult = _decoder.decode(xmlData);
+        if (packet.result is ErrorMessage)
+        {
+            _wrappedResponder.status(ErrorMessage(packet.result));
+        }
+        else if (packet.result is AsyncMessage)
+        {
+            _wrappedResponder.result(AsyncMessage(packet.result));
+        }
+    }
+
+    /**
+     *  @private
+     *  Handles an error for an outbound request.
+     *
+     *  @param event The error event from the associated URLLoader.
+     */
+    public function errorHandler(event:Event):void
+    {
+        var msg:ErrorMessage = new ErrorMessage();
+        msg.correlationId = _wrappedResponder.message.messageId;
+        msg.faultCode = "Server.Error.Request";
+        msg.faultString = resourceManager.getString(
+            "messaging", "httpRequestError");
+        var details:String = event.toString();
+        if (_wrappedResponder.message is HTTPRequestMessage)
+        {
+            details += ". URL: ";
+            details += HTTPRequestMessage(_wrappedResponder.message).url;
+        }
+        msg.faultDetail = resourceManager.getString(
+            "messaging", "httpRequestError.details", [ details ]);
+        msg.rootCause = event;
+        _wrappedResponder.status(msg);
+    }
+}
+
+
+[ResourceBundle("messaging")]
+
+/**
+ *  @private
+ *  This is an adapter for url loader that is used by the HTTPChannel.
+ */
+class HTTPMessageResponder extends MessageResponder
+{
+    
//--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Constructs an HTTPMessageResponder.
+     *
+     *  @param agent The associated MessageAgent.
+     *
+     *  @param msg The message to send.
+     *
+     *  @param channel The Channel to send the message over.
+     */
+    public function HTTPMessageResponder
+        (agent:MessageAgent, msg:IMessage, channel:HTTPChannel)
+    {
+        super(agent, msg, channel);
+        decoder = new AMFXDecoder();
+        urlLoader = new ChannelRequestLoader();
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Variables
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private var decoder:AMFXDecoder;
+
+    /**
+     * @private
+     */
+    private var resourceManager:IResourceManager =
+                                    ResourceManager.getInstance();
+
+    
//--------------------------------------------------------------------------
+    //
+    // Properties
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  The loader associated with this responder.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public var urlLoader:ChannelRequestLoader;
+
+    
//--------------------------------------------------------------------------
+    //
+    // Overridden Protected Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    override protected function resultHandler(response:IMessage):void
+    {
+        var errorMsg:ErrorMessage;
+
+        if (response is AsyncMessage)
+        {
+            if (response is ErrorMessage)
+            {
+                agent.fault(ErrorMessage(response), message);
+            }
+            else if (AsyncMessage(response).correlationId == message.messageId)
+            {
+                agent.acknowledge(AcknowledgeMessage(response), message);
+            }
+            else
+            {
+                errorMsg = new ErrorMessage();
+                errorMsg.faultCode = "Server.Acknowledge.Failed";
+                errorMsg.faultString = resourceManager.getString(
+                    "messaging", "ackFailed");
+                errorMsg.faultDetail = resourceManager.getString(
+                    "messaging", "ackFailed.details",
+                    [ message.messageId, AsyncMessage(response).correlationId 
]);
+                agent.fault(errorMsg, message);
+            }
+        }
+        else if (response != null)
+        {
+            errorMsg = new ErrorMessage();
+            errorMsg.faultCode = "Server.Acknowledge.Failed";
+            errorMsg.faultString = resourceManager.getString(
+                "messaging", "noAckMessage");
+            errorMsg.faultDetail = resourceManager.getString(
+                "messaging", "noAckMessage.details",
+                [ mx.utils.ObjectUtil.toString(response) ]);
+            agent.fault(errorMsg, message);
+        }
+    }
+
+    /**
+     *  @private
+     *  Handle a request timeout by closing our associated URLLoader and
+     *  faulting the message to the agent.
+     */
+    override protected function requestTimedOut():void
+    {
+        urlLoader.close();
+
+        status(null);
+        // send the ack
+        var ack:AcknowledgeMessage = new AcknowledgeMessage();
+        ack.correlationId = message.messageId;
+        ack.headers[AcknowledgeMessage.ERROR_HINT_HEADER] = true; // hint 
there was an error
+        agent.acknowledge(ack, message);
+        // send the fault
+        agent.fault(createRequestTimeoutErrorMessage(), message);
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    final public function completeHandler(event:Event):void
+    {
+        result(null);
+
+        var raw:String = String(URLLoader(event.target).data);
+        var xmlData:XML = new XML(raw);
+        var packet:AMFXResult = decoder.decode(xmlData);
+
+        if (packet.result is IMessage)
+        {
+            resultHandler(IMessage(packet.result));
+        }
+    }
+
+    /**
+     *  @private
+     */
+    public function errorHandler(event:Event):void
+    {
+        status(null);
+        // send the ack
+        var ack:AcknowledgeMessage = new AcknowledgeMessage();
+        ack.correlationId = message.messageId;
+        ack.headers[AcknowledgeMessage.ERROR_HINT_HEADER] = true; // hint 
there was an error
+        agent.acknowledge(ack, message);
+        // send fault
+        var msg:ErrorMessage = new ErrorMessage();
+        msg.correlationId = message.messageId;
+        msg.faultCode = "Server.Error.Request";
+        msg.faultString = resourceManager.getString(
+            "messaging", "httpRequestError");
+        var details:String = event.toString();
+        if (message is HTTPRequestMessage)
+        {
+            details += ". URL: ";
+            details += HTTPRequestMessage(message).url;
+        }
+        msg.faultDetail = resourceManager.getString(
+            "messaging", "httpRequestError.details", [ details ]);
+        msg.rootCause = event;
+        agent.fault(msg, message);
+    }
+
+    /**
+     *  @private
+     */
+    public function ioErrorHandler(event:Event):void
+    {
+        status(null);
+        // send the ack
+        var ack:AcknowledgeMessage = new AcknowledgeMessage();
+        ack.correlationId = message.messageId;
+        ack.headers[AcknowledgeMessage.ERROR_HINT_HEADER] = true; // hint 
there was an error
+        agent.acknowledge(ack, message);
+        // send fault
+        var msg:ErrorMessage = new ErrorMessage();
+        msg.correlationId = message.messageId;
+        msg.faultCode = "Server.Error.Request";
+        msg.faultString = resourceManager.getString(
+            "messaging", "httpRequestError");
+        var details:String = event.toString();
+        if (message is HTTPRequestMessage)
+        {
+            details += ". URL: ";
+            details += HTTPRequestMessage(message).url;
+        }
+        msg.faultDetail = resourceManager.getString(
+            "messaging", "httpRequestError.details", [ details ]);
+        msg.rootCause = event;
+
+        (channel as HTTPChannel).connectionError(msg);
+        
+        // already disconnected, now let the agent know the the message faulted
+        // this is similar to the disconnect() and fault() in the 
NetConnectionChannel statusHandler
+        agent.fault(msg, message);    
+    }
+
+    /**
+     *  @private
+     */
+    public function securityErrorHandler(event:Event):void
+    {
+        status(null);
+        // send the ack
+        var ack:AcknowledgeMessage = new AcknowledgeMessage();
+        ack.correlationId = message.messageId;
+        ack.headers[AcknowledgeMessage.ERROR_HINT_HEADER] = true; // hint 
there was an error
+        agent.acknowledge(ack, message);
+        // send fault
+        var msg:ErrorMessage = new ErrorMessage();
+        msg.correlationId = message.messageId;
+        msg.faultCode = "Channel.Security.Error";
+        msg.faultString = resourceManager.getString(
+            "messaging", "securityError");
+        msg.faultDetail = resourceManager.getString(
+            "messaging", "securityError.details", [ message.destination ]);
+        msg.rootCause = event;
+        agent.fault(msg, message);
+    }
+}
+
+/**
+ *  @private
+ *  Wraps an URLLoader and manages dispatching its events to the proper 
handlers.
+ */
+class ChannelRequestLoader
+{
+    
//--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Constructs a ChannelRequestLoader.
+     */
+    public function ChannelRequestLoader()
+    {
+        super();
+        _urlLoader = new URLLoader();
+        _urlLoader.addEventListener(ErrorEvent.ERROR, errorHandler);
+        _urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
+        _urlLoader.addEventListener
+            (SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
+        _urlLoader.addEventListener(Event.COMPLETE, completeHandler);
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Variables
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  The wrapped URLLoader.
+     */
+    private var _urlLoader:URLLoader;
+
+    
//--------------------------------------------------------------------------
+    //
+    // Properties
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    public var errorCallback:Function;
+
+    /**
+     *  @private
+     */
+    public var ioErrorCallback:Function;
+
+    /**
+     *  @private
+     */
+    public var securityErrorCallback:Function;
+
+    /**
+     *  @private
+     */
+    public var completeCallback:Function;
+
+    /**
+     *  @private
+     */
+    public var requestProcessedCallback:Function;
+
+    
//--------------------------------------------------------------------------
+    //
+    // Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    public function load(request:URLRequest):void
+    {
+        _urlLoader.load(request);
+    }
+
+    /**
+     *  @private
+     */
+    public function close():void
+    {
+        _urlLoader.removeEventListener(ErrorEvent.ERROR, errorHandler);
+        _urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
+        _urlLoader.removeEventListener
+            (SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
+        _urlLoader.removeEventListener(Event.COMPLETE, completeHandler);
+        _urlLoader.close();
+    }
+
+    /**
+     *  @private
+     */
+    public function setErrorCallbacks(callback:Function):void
+    {
+        errorCallback = callback;
+        ioErrorCallback = callback;
+        securityErrorCallback = callback;
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Private Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private function callRequestProcessedCallback(event:Event):void
+    {
+        if (requestProcessedCallback != null)
+            requestProcessedCallback(this, event);
+    }
+
+    /**
+     *  @private
+     */
+    private function callEventCallback(callback:Function, event:Event):void
+    {
+        if (callback != null)
+            callback(event);
+    }
+
+    /**
+     *  @private
+     */
+    private function errorHandler(event:Event):void
+    {
+        callRequestProcessedCallback(event);
+        callEventCallback(requestProcessedCallback, event);
+    }
+
+    /**
+     *  @private
+     */
+    private function ioErrorHandler(event:Event):void
+    {
+        callRequestProcessedCallback(event);
+        callEventCallback(ioErrorCallback, event);
+    }
+
+    /**
+     *  @private
+     */
+    private function securityErrorHandler(event:Event):void
+    {
+        callRequestProcessedCallback(event);
+        callEventCallback(securityErrorCallback, event);
+    }
+
+    /**
+     *  @private
+     */
+    private function completeHandler(event:Event):void
+    {
+        callRequestProcessedCallback(event);
+        callEventCallback(completeCallback, event);
+    }
+}
\ No newline at end of file
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/SecureHTTPChannel.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/SecureHTTPChannel.as
new file mode 100644
index 0000000..87e4a83
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/SecureHTTPChannel.as
@@ -0,0 +1,80 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.messaging.channels
+{
+
+/**
+ *  The SecureHTTPChannel class is identical to the HTTPChannel class except 
that it uses a
+ *  secure protocol, HTTPS, to send messages to an HTTP endpoint.
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion BlazeDS 4
+ *  @productversion LCDS 3 
+ */
+public class SecureHTTPChannel extends HTTPChannel
+{
+    
//--------------------------------------------------------------------------
+    //
+    // Constructor
+    // 
+    
//--------------------------------------------------------------------------
+    
+    /**
+     *  Constructor.
+     *
+     *  @param id The id of this Channel.
+     *  
+     *  @param uri The uri for this Channel.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function SecureHTTPChannel(id:String = null, uri:String = null)
+    {
+        super(id, uri);
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Properties
+    // 
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  Returns the protocol for this channel (https).
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    override public function get protocol():String
+    {
+        return "https";
+    }
+}
+
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXContext.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXContext.as
new file mode 100644
index 0000000..fe4caf9
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXContext.as
@@ -0,0 +1,304 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.messaging.channels.amfx
+{
+
+import mx.logging.ILogger;
+
+[ExcludeClass]
+
+/**
+ * Holds a list of complex object references, object trait info references,
+ * or string references generated while encoding or decoding and AMFX packet.
+ * Note that a new set of reference tables should be used per AMFX packet.
+ * Calling reset() will create new tables for each of these types of 
references.
+ * @private
+ */
+public class AMFXContext
+{
+    /**
+     * Constructor.
+     * Initializes object, trait info and string reference tables.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function AMFXContext()
+    {
+        super();
+        reset();
+    }
+
+    /**
+     * Resets the trait info, object and string reference tables.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function reset():void
+    {
+        traits = [];
+        objects = [];
+        strings = [];
+    }
+
+    /**
+     * Check whether the trait info reference table
+     * already contains this list of traits. If found,
+     * the index of the trait info is returned, starting
+     * from 0. If not found -1 is returned.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function findTraitInfo(traitInfo:Object):int
+    {
+        for (var i:uint = 0; i < traits.length; i++)
+        {
+            var ti:Object = traits[i];
+
+            if (ti.alias == traitInfo.alias
+                && ti.properties.length == traitInfo.properties.length)
+            {
+                var j:uint = 0;
+                for (; j < ti.properties.length; j++)
+                {
+                    if (ti.properties[i] != traitInfo.properties[j])
+                    {
+                        break;
+                    }
+                }
+
+                if (j == traitInfo.properties.length)
+                {
+                    //Match found
+                    return i;
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Check whether the object reference table
+     * already contains this object. If found, the index
+     * of the object is returned, starting from 0. If
+     * not found -1 is returned.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function findObject(object:Object):int
+    {
+        for (var i:uint = 0; i < objects.length; i++)
+        {
+            var o:Object = objects[i];
+            if (o === object)
+            {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Check whether the string reference table
+     * already contains this string. If found, the index
+     * of the string is returned, starting from 0. If
+     * not found (or if the value passed is the empty string)
+     * -1 is returned.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function findString(str:String):int
+    {
+        if (str != "")
+        {
+            for (var i:uint = 0; i < strings.length; i++)
+            {
+                var s:String = strings[i];
+                if (s == str)
+                {
+                    return i;
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Remember the trait info for an object in this context
+     * for an encoding or decoding session.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function addTraitInfo(traitInfo:Object):void
+    {
+        traits.push(traitInfo);
+    }
+
+    /**
+     * Remember an object in this context for an encoding
+     * or decoding session.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function addObject(obj:Object):void
+    {
+        objects.push(obj);
+    }
+
+    /**
+     * Remember a string in this context for an encoding
+     * or decoding session. Note that the empty string
+     * is not remembered as it should not be serialized
+     * by reference.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function addString(str:String):void
+    {
+        if (str != "")
+        {
+            strings.push(str);
+        }
+    }
+
+
+    /**
+     * Retrieve trait info for an object by its reference
+     * table index.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function getTraitInfo(ref:uint):*
+    {
+        return traits[ref];
+    }
+
+    /**
+     * Retrieve an object by its reference table index.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function getObject(ref:uint):*
+    {
+        return objects[ref];
+    }
+
+    /**
+     * Retrieve a string by its reference table index.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public function getString(ref:uint):String
+    {
+        return strings[ref];
+    }
+
+    /**
+     * Trait Info reference table
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    internal var traits:Array;
+
+    /**
+     * Object reference table
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    internal var objects:Array;
+
+    /**
+     * Strings reference table
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    internal var strings:Array;
+
+    /**
+     * Log for the current encoder/decoder context.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3 
+     */
+    public var log:ILogger;
+}
+
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXDecoder.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXDecoder.as
new file mode 100644
index 0000000..7772695
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXDecoder.as
@@ -0,0 +1,638 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.messaging.channels.amfx
+{
+
+import org.apache.royale.reflection.getClassByAlias;
+import mx.utils.ByteArray;
+//import flash.utils.Dictionary;
+import org.apache.royale.utils.net.IExternalizable;
+import org.apache.royale.reflection.getDefinitionByName;
+
+import mx.logging.Log;
+import mx.messaging.errors.ChannelError;
+import mx.resources.IResourceManager;
+import mx.resources.ResourceManager;
+import mx.utils.HexDecoder;
+
+[ResourceBundle("messaging")]
+
+[ExcludeClass]
+
+/**
+ * Decodes an AMFX packet into an ActionScript Object graph.
+ * Headers and the result body are accessed from the returned
+ * AMFXResult.
+ * @private
+ */
+public class AMFXDecoder
+{
+    
//--------------------------------------------------------------------------
+    //
+    // Constructor
+    // 
+    
//--------------------------------------------------------------------------
+
+    public function AMFXDecoder()
+    {
+        super();
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Class variables
+    // 
+    
//--------------------------------------------------------------------------
+
+       /**
+        *  @private
+        *  Storage for the resourceManager getter.
+        *  This gets initialized on first access,
+        *  not at static initialization time, in order to ensure
+        *  that the Singleton registry has already been initialized.
+        */
+       private static var _resourceManager:IResourceManager;
+       
+       /**
+        *  @private
+     *  A reference to the object which manages
+     *  all of the application's localized resources.
+     *  This is a singleton instance which implements
+     *  the IResourceManager interface.
+        */
+       private static function get resourceManager():IResourceManager
+       {
+               if (!_resourceManager)
+                       _resourceManager = ResourceManager.getInstance();
+
+               return _resourceManager;
+       }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Public Methods
+    // 
+    
//--------------------------------------------------------------------------
+    
+    public function decode(xml:XML):AMFXResult
+    {
+        if (xml)
+        {
+            var context:AMFXContext = new AMFXContext();
+            context.log = 
Log.getLogger("mx.messaging.channels.amfx.AMFXDecoder");
+            XML.ignoreWhitespace = false;
+            return decodePacket(xml, context);
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Static Methods
+    // 
+    
//--------------------------------------------------------------------------
+
+    private static function decodePacket(xml:XML, 
context:AMFXContext):AMFXResult
+    {
+        var result:AMFXResult = new AMFXResult();
+
+        var message:String;
+               
+               var name:String = xml.localName() as String;
+        if (name == "amfx")
+        {
+            var v:String = xml.attribute("ver").toString();
+            var version:uint = uint(v);
+
+            if (supportedVersion(version))
+            {
+                var h:XMLList = xml.child("header");
+                if (h)
+                {
+                    result.headers = decodeHeaders(h, context);
+                }
+
+                var body:XML = xml.body[0];
+
+                if (body)
+                {
+                    result.result = decodeBody(body, context);
+                }
+                else
+                {
+                                       message = resourceManager.getString(
+                                               "messaging", "noAMFXBody");
+                    throw new ChannelError(message);
+                }
+            }
+            else
+            {
+                               message = resourceManager.getString(
+                                       "messaging", "unsupportedAMFXVersion", 
[ version ]);
+                throw new ChannelError(message);
+            }
+        }
+        else
+        {
+                       message = resourceManager.getString(
+                               "messaging", "noAMFXNode")
+            throw new ChannelError(message);
+        }
+
+        return result;
+    }
+
+    private static function decodeHeaders(xmlList:XMLList, 
context:AMFXContext):Array
+    {
+        var headers:Array = [];
+
+        for (var i:uint = 0; i < xmlList.length(); i++)
+        {
+            var h:XML = xmlList[i];
+            var name:String = h.attribute("name").toString();
+
+            var header:AMFXHeader = new AMFXHeader();
+            header.name = name;
+
+            var temp:String = h.attribute("mustUnderstand").toString();
+            header.mustUnderstand = (temp == "true");
+
+            var children:XMLList = h.children();
+            if (children.length() > 0)
+            {
+                header.content = decodeValue(children[0], context);
+            }
+            else
+            {
+                header.content = null;
+            }
+            
+            headers[i] = header;
+        }
+
+        return headers;
+    }
+
+    private static function decodeBody(xml:XML, context:AMFXContext):Object
+    {
+        var result:Object;
+        var children:XMLList = xml.children();
+
+        if (children.length() == 1)
+        {
+            result = decodeValue(children[0], context);
+        }
+        else if (children.length() > 1)
+        {
+            result = [];
+            for (var i:uint = 0; i < children.length(); i++)
+            {
+                result[i] = decodeValue(children[i], context);
+            }
+        }
+
+        return result;
+    }
+
+    public static function decodeValue(xml:XML, context:AMFXContext):Object
+    {
+        var result:Object;
+        var name:String = xml.localName() as String;
+
+        if (name == "string")
+        {
+            result = decodeString(xml, context);
+        }
+        else if (name == "true")
+        {
+            result = true;
+        }
+        else if (name == "false")
+        {
+            result = false;
+        }
+        else if (name == "array")
+        {
+            result = decodeArray(xml, context);
+        }
+        else if (name == "object")
+        {
+            result = decodeObject(xml, context);
+        }
+        else if (name == "ref")
+        {
+            result = decodeRef(xml, context);
+        }
+        /*
+        else if (name == "dictionary")
+        {
+            result = decodeDictionary(xml, context);
+        }*/
+        else if (name == "double")
+        {
+            var n:String = xml.text().toString();
+            result = Number(n);
+        }
+        else if (name == "int")
+        {
+            var i:String = xml.text().toString();
+            result = int(i);
+        }
+        else if (name == "null")
+        {
+            result = null;
+        }
+        else if (name == "date")
+        {
+            result = decodeDate(xml, context);
+        }
+        else if (name == "xml")
+        {
+            var x:String = xml.text().toString();
+            // If we had CDATA, restore any escaped close CDATA "]]>" tokens
+            if (hasEscapedCloseCDATA(xml))
+            {
+                x = x.replace(REGEX_CLOSE_CDATA, "]]>");
+            }
+
+            result = new XML(x);
+        }
+        else if (name == "bytearray")
+        {        
+            result = decodeByteArray(xml);
+        }
+        else if (name == "undefined")
+        {
+            result = undefined;
+        }
+
+        return result;
+    }
+
+    private static function decodeArray(xml:XML, context:AMFXContext):Array
+    {
+        var array:Array = [];
+
+        // Remember Array
+        context.addObject(array);
+
+        var entries:XMLList = xml.*;
+        if (entries)
+        {
+            for (var i:uint = 0; i < entries.length(); i++)
+            {
+                var x:XML = entries[i];
+                var prop:Object;
+                if (x.localName() == "item")
+                {
+                    var propName:String = x.attribute("name").toString();
+                    prop = decodeValue(x.*[0], context);
+                    array[propName] = prop;
+                }
+                else
+                {
+                    prop = decodeValue(x, context);
+                    array.push(prop);
+                }
+            }
+        }
+
+        return array;
+    }
+
+    /*
+    private static function decodeDictionary(xml:XML, 
context:AMFXContext):Dictionary
+    {
+        var dictionary:Dictionary = new Dictionary();
+
+        context.addObject(dictionary); // Remember the dictionary.
+
+        var entries:XMLList = xml.*;
+        if (entries == null)
+            return dictionary;
+
+        for (var i:uint = 0; i < entries.length(); i = i + 2)
+        {
+            var keyXml:XML = entries[i];
+            var valueXml:XML = entries[i + 1];
+            var key:Object= decodeValue(keyXml, context);
+            var value:Object = decodeValue(valueXml, context);
+            dictionary[key] = value;
+        }
+
+        return dictionary;
+    }
+    */
+
+    private static function decodeByteArray(xml:XML):ByteArray
+    {
+        var str:String = xml.text().toString();
+
+        var decoder:HexDecoder = new HexDecoder();
+        decoder.decode(str);
+        return decoder.drain();
+    }
+
+    private static function decodeDate(xml:XML, context:AMFXContext):Date
+    {
+        var d:String = xml.text().toString();
+        var time:Number = new Number(d);
+        var result:Date = new Date();
+        result.setTime(time);
+
+        // Remember Date object
+        context.addObject(result);
+
+        return result;
+    }
+
+    private static function decodeObject(xml:XML, context:AMFXContext):Object
+    {
+        var result:Object;
+        var className:String = xml.attribute("type").toString();
+
+        if (className)
+        {
+            try
+            {
+                var classType:Class = null;
+                try
+                {
+                    classType = getClassByAlias(className);
+                }
+                catch(e1:Error)
+                {
+                    if (!classType)
+                        classType = getDefinitionByName(className) as Class;
+                }
+
+                result = new classType();
+            }
+            catch(e:Error)
+            {
+                if (context.log)
+                    context.log.warn("Error instantiating class: {0}. 
Reverting to anonymous Object.", className);
+
+                result = {};
+            }
+        }
+        else
+        {
+            className = "Object";
+            result = {};
+        }
+
+        // Remember Object
+        context.addObject(result);
+
+        var entries:XMLList = xml.*;
+
+        if (entries && entries.length() > 0)
+        {
+            var traits:Object;
+            var tx:XML = entries[0];
+                       var message:String;
+
+            if (tx.localName() == "traits")
+            {
+                traits = decodeTraits(tx, className, context);
+                delete entries[0];
+            }
+
+            if (!traits)
+            {
+                               message = resourceManager.getString(
+                                       "messaging", "AMFXTraitsNotFirst")
+                throw new ChannelError(message);
+            }
+
+            if (traits.externalizable)
+            {
+                if (result is IExternalizable)
+                {
+                    var ext:IExternalizable = IExternalizable(result);
+                    tx = entries[0];
+                    if (tx.localName() == "bytearray")
+                    {
+                        var ba:ByteArray = decodeByteArray(tx);
+
+                        try
+                        {
+                            ext.readExternal(ba);
+                        }
+                        catch(e:Error)
+                        {
+                                                       message = 
resourceManager.getString(
+                                                               "messaging", 
"errorReadingIExternalizable",
+                                                               [ 
(e.message/*+e.getStackTrace()*/) ]);
+                            throw new ChannelError(message);
+                        }
+                    }
+                }
+                else
+                {
+                                       message = resourceManager.getString(
+                                               "messaging", 
"notImplementingIExternalizable",
+                                               [ className ]);
+                    throw new ChannelError(message);
+                }
+            }
+            else
+            {
+                for (var i:uint = 0; i < entries.length(); i++)
+                {
+                    var propName:String = traits.properties[i];
+                    var propValue:* = decodeValue(entries[i], context);
+
+                    try
+                    {
+                        result[propName] = propValue;
+                    }
+                    catch(e2:Error)
+                    {
+                        if (context.log != null)
+                            context.log.warn("Cannot set property '{0}' on 
type '{1}'.", propName, className);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    private static function decodeRef(xml:XML, context:AMFXContext):Object
+    {
+        var result:*;
+
+               var message:String;
+
+        var idAttr:String = xml.attribute("id").toString();
+        if (idAttr)
+        {
+            var ref:int = parseInt(idAttr);
+
+            if (!isNaN(ref))
+            {
+                result = context.getObject(ref);
+            }
+
+            if (result === undefined)
+            {
+                               message = resourceManager.getString(
+                                       "messaging", "unknownReference", [ 
idAttr ]);
+                throw new ChannelError(message);
+            }
+        }
+        else
+        {
+                       message = resourceManager.getString(
+                               "messaging", "referenceMissingId");
+            throw new ChannelError(message);
+        }
+
+        return result;
+    }
+
+    private static function decodeString(xml:XML, context:AMFXContext, 
isTrait:Boolean = false):String
+    {
+        var str:String;
+
+        var refAttr:String = xml.attribute("id").toString();
+        if (refAttr)
+        {
+            var ref:uint = uint(refAttr);
+            if (!isNaN(ref))
+            {
+                str = context.getString(ref);
+            }
+
+            if (!str)
+            {
+                               var message:String = resourceManager.getString(
+                                       "messaging", "unknownStringReference", 
[ refAttr ]);
+                throw new ChannelError(message);
+            }
+        }
+        else
+        {
+            str = xml.text().toString();
+
+            // If we had CDATA, restore any escaped close CDATA "]]>" tokens
+            // Note that trait names won't have CDATA sections... so no need 
to check them
+            if (!isTrait && hasEscapedCloseCDATA(xml))
+            {
+                str = str.replace(REGEX_CLOSE_CDATA, "]]>");
+            }
+
+            //Remember string
+            context.addString(str);
+        }
+
+        return str;
+    }
+
+    private static function decodeTraits(xml:XML, className:String, 
context:AMFXContext):Object
+    {
+        var traits:Object;
+
+        var refAttr:String = xml.attribute("id").toString();
+        if (refAttr)
+        {
+            var ref:uint = uint(refAttr);
+            if (!isNaN(ref))
+            {
+                traits = context.getTraitInfo(ref);
+            }
+
+            if (!traits)
+            {
+                               var message:String = resourceManager.getString(
+                                       "messaging", "unknownTraitReference", [ 
refAttr ]);
+                throw new ChannelError(message);
+            }
+        }
+        else
+        {
+            traits = {};
+            traits.name = className;
+            traits.alias = className;
+            traits.properties = [];
+            traits.externalizable = false;
+
+            var ext:String = xml.attribute("externalizable").toString();
+            if (ext == "true")
+            {
+                traits.externalizable = true;
+            }
+
+            var nodes:XMLList = xml.*;
+            if (nodes)
+            {
+                for (var i:uint = 0; i < nodes.length(); i++)
+                {
+                    traits.properties[i] = decodeString(nodes[i], context, 
true);
+                }
+            }
+
+            //Remember traits
+            context.addTraitInfo(traits);
+        }
+
+        return traits;
+    }
+
+    private static function hasEscapedCloseCDATA(xml:XML):Boolean
+    {
+        var s:String = xml.toXMLString();
+
+        if (s.indexOf("]]>") != -1)
+        {
+            return s.indexOf("]]&gt;") != -1;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    private static function supportedVersion(ver:uint):Boolean
+    {
+        for (var i:uint = 0; i < SUPPORTED_VERSIONS.length; i++)
+        {
+            if (ver == SUPPORTED_VERSIONS[i])
+                return true;
+        }
+
+        return false;
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    // Static Constants
+    // 
+    
//--------------------------------------------------------------------------
+
+    private static const SUPPORTED_VERSIONS:Array = [3];
+    private static const REGEX_CLOSE_CDATA:RegExp = new RegExp("]]&gt;", "g");
+}
+
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXEncoder.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXEncoder.as
new file mode 100644
index 0000000..44cf733
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXEncoder.as
@@ -0,0 +1,510 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.messaging.channels.amfx
+{
+
+import mx.utils.ByteArray;
+//import flash.utils.Dictionary;
+import org.apache.royale.utils.net.IExternalizable;
+//import flash.utils.describeType;
+//import flash.xml.XMLDocument;
+
+import mx.logging.Log;
+import mx.utils.HexEncoder;
+import mx.utils.ObjectProxy;
+import mx.utils.ObjectUtil;
+
+[ExcludeClass]
+
+/**
+ * Serializes an arbitrary ActionScript object graph to an XML
+ * representation that is based on Action Message Format (AMF)
+ * version 3.
+ * @private
+ */
+public class AMFXEncoder
+{
+    public function AMFXEncoder()
+    {
+        super();
+        settings = {};
+        settings.prettyPrinting = false;
+    }
+
+    public function encode(obj:Object, headers:Array = null):XML
+    {
+        XML.setSettings(settings);
+        var xml:XML = new XML("<amfx />");
+        xml.setNamespace(NAMESPACE);
+        xml.@["ver"] = CURRENT_VERSION;
+
+        var context:AMFXContext = new AMFXContext();
+        context.log = Log.getLogger("mx.messaging.channels.amfx.AMFXEncoder");
+        encodePacket(xml, obj, headers, context);
+
+        return xml;
+    }
+
+    private static function encodePacket(xml:XML, obj:Object, headers:Array = 
null, context:AMFXContext = null):void
+    {
+        if (headers)
+            encodeHeaders(xml, headers, context);
+        encodeBody(xml, obj, context);
+    }
+
+    private static function encodeHeaders(xml:XML, headers:Array, 
context:AMFXContext):void
+    {
+        for (var i:uint = 0; i < headers.length; i++)
+        {
+            var header:Object = headers[i];
+            var element:XML = <header />;
+            element.@["name"] = header.name;
+            element.@["mustUnderstand"] = (header.mustUnderstand == true);
+            encodeValue(element, header.content, context);
+            xml.appendChild(element);
+        }
+    }
+
+    private static function encodeBody(xml:XML, obj:*, 
context:AMFXContext):void
+    {
+        var element:XML = <body />;
+        //element.@["targetURI"] = ""; //TODO: Support this attribute
+        encodeValue(element, obj, context);
+        xml.appendChild(element);
+    }
+
+    public static function encodeValue(xml:XML, obj:*, 
context:AMFXContext):void
+    {
+        if (obj != null)
+        {
+            if (obj is String)
+            {
+                encodeString(xml, String(obj), context);
+            }
+            else if (obj is Number)
+            {
+                encodeNumber(xml, Number(obj));
+            }
+            else if (obj is Boolean)
+            {
+                encodeBoolean(xml, Boolean(obj));
+            }
+            else if (obj is ByteArray)
+            {
+                encodeByteArray(xml, ByteArray(obj));
+            }
+            else if (obj is Array)
+            {
+                encodeArray(xml, obj as Array, context);
+            }
+            /*
+            else if (obj is XML || obj is XMLDocument)
+            {
+                encodeXML(xml, obj);
+            }*/
+            else if (obj is Date)
+            {
+                encodeDate(xml, obj as Date, context);
+            }
+            else if (obj is Class)
+            {
+                //TODO: Throw errors for unsupported types?
+                if (context.log)
+                    context.log.warn("Cannot serialize type Class");
+            }
+            /*
+            else if (obj is Dictionary)
+            {
+                encodeDictionary(xml, obj as Dictionary, context);
+            }*/
+            else
+            {
+                encodeObject(xml, obj, context);
+            }
+        }
+        else if (obj === undefined)
+        {
+            xml.appendChild(X_UNDEFINED.copy());
+        }
+        else
+        {
+            xml.appendChild(X_NULL.copy());
+        }
+    }
+
+
+    private static function encodeArray(xml:XML, array:Array, 
context:AMFXContext):void
+    {
+        var ref:int = context.findObject(array);
+        var element:XML;
+        if (ref >= 0)
+        {
+            element = <ref />
+            element.@["id"] = String(ref);
+        }
+        else
+        {
+            rememberObject(context, array);
+
+            element = <array />;
+
+            var named:Object = {};
+            var ordinal:Array = [];
+            var isECMAArray:Boolean = false;
+
+            // Separate named and ordinal array members
+            for (var member:String in array)
+            {
+                if (isNaN(Number(member)))
+                {
+                    named[member] = array[member];
+                    isECMAArray = true;
+                }
+                else
+                {
+                    var num:int = parseInt(member);
+                    ordinal[num] = array[num];
+                }
+            }
+
+            // Encode named items as early as possible
+            for (var n:String in named)
+            {
+                encodeArrayItem(element, n, named[n], context);
+            }
+
+            var ordinalLength:uint = 0;
+            var dense:Boolean = true;
+            for (var i:uint = 0; i < ordinal.length; i++)
+            {
+                var o:* = ordinal[i];
+
+                // If we have an undefined slot remaining ordinal
+                // keys will be converted to named keys to preserve dense set
+                if (o !== undefined)
+                {
+                    if (dense)
+                    {
+                        encodeValue(element, o, context);
+                        ordinalLength++;
+                    }
+                    else
+                    {
+                        isECMAArray = true;
+                        encodeArrayItem(element, String(i), o, context);
+                    }
+                }
+                else
+                {
+                    dense = false;
+                }
+            }
+
+            element.@["length"] = String(ordinalLength);
+
+            if (isECMAArray)
+            {
+                element.@["ecma"] = "true";
+            }
+        }
+
+        xml.appendChild(element);
+    }
+
+    private static function encodeArrayItem(xml:XML, name:String, value:*, 
context:AMFXContext):void
+    {
+        var item:XML = <item />;
+        item.@["name"] = name;
+        encodeValue(item, value, context);
+        xml.appendChild(item);
+    }
+
+    private static function encodeBoolean(xml:XML, bool:Boolean):void
+    {
+        if (bool)
+            xml.appendChild(X_TRUE.copy());
+        else
+            xml.appendChild(X_FALSE.copy());
+    }
+
+
+    private static function encodeByteArray(xml:XML, obj:ByteArray):void
+    {
+        var element:XML = <bytearray/>;
+        var encoder:HexEncoder = new HexEncoder();
+        encoder.encode(obj);
+        var encoded:String = encoder.flush();
+        element.appendChild(encoded);
+        xml.appendChild(element);
+    }
+
+    private static function encodeDate(xml:XML, date:Date, 
context:AMFXContext):void
+    {
+        var ref:int = context.findObject(date);
+        var element:XML;
+        if (ref >= 0)
+        {
+            element = <ref />
+            element.@["id"] = String(ref);
+        }
+        else
+        {
+            rememberObject(context, date);
+
+            element = <date />;
+            element.appendChild(new XML(date.getTime().toString()));
+        }
+        xml.appendChild(element);
+    }
+
+    private static function encodeNumber(xml:XML, num:Number):void
+    {
+        var element:XML = null;
+        if (num is int || num is uint)
+        {
+            element = <int />;
+        }
+        else
+        {
+            element = <double />;
+        }
+        element.appendChild(new XML(num.toString()));
+        xml.appendChild(element);
+
+    }
+
+    /*
+    private static function encodeDictionary(xml:XML, dict:Dictionary, 
context:AMFXContext):void
+    {
+        var ref:int = context.findObject(dict);
+        var element:XML;
+        if (ref >= 0)
+        {
+            element = <ref />;
+            element.@["id"] = String(ref);
+        }
+        else
+        {
+            rememberObject(context, dict);
+
+            element = <dictionary />;
+
+            var classInfo:Object = ObjectUtil.getClassInfo(dict, null, 
CLASS_INFO_OPTIONS);
+            var properties:Array = classInfo.properties;
+            var count:uint = properties.length;
+
+            for (var i:uint = 0; i < count; i++)
+            {
+                var prop:Object = properties[i];
+                encodeValue(element, prop, context);
+                encodeValue(element, dict[prop], context);
+            }
+        }
+        element.@["length"] = String(count);
+        xml.appendChild(element);
+    }
+    */
+    
+    private static function rememberObject(context:AMFXContext, obj:*):void
+    {
+        context.addObject(obj);
+    }
+
+    private static function encodeObject(xml:XML, obj:*, 
context:AMFXContext):void
+    {
+        var ref:int = context.findObject(obj);
+        var element:XML;
+        if (ref >= 0)
+        {
+            element = <ref />
+            element.@["id"] = String(ref);
+        }
+        else
+        {
+            rememberObject(context, obj);
+
+            element = <object />;
+
+            var classInfo:Object = ObjectUtil.getClassInfo(obj, null, 
CLASS_INFO_OPTIONS);
+            var className:String = classInfo.name;
+            var classAlias:String = classInfo.alias;
+            var properties:Array = classInfo.properties;
+            var count:uint = properties.length;
+
+            // We need to special case ObjectProxy as for serialization we 
actually need the
+            // remote alias of ObjectProxy, not the wrapped object.
+            /*
+            if (obj is ObjectProxy)
+            {
+                var cinfo:XML = describeType(obj);
+                className = [email protected]();
+                classAlias = [email protected]();
+            }
+            */
+            
+            var remoteClassName:String = ((classAlias != null) ? classAlias : 
className);
+
+            if (remoteClassName && remoteClassName != "Object" && 
remoteClassName != "Array")
+            {
+                element.@["type"] = remoteClassName.replace(REGEX_CLASSNAME, 
".");
+            }
+
+            if (obj is IExternalizable)
+            {
+                classInfo.externalizable = true;
+                encodeTraits(element, classInfo, context);
+
+                var ext:IExternalizable = IExternalizable(obj);
+                var ba:ByteArray = new ByteArray();
+                ext.writeExternal(ba);
+                encodeByteArray(element, ba);
+            }
+            else
+            {
+                classInfo.externalizable = false;
+                encodeTraits(element, classInfo, context);
+
+                for (var i:uint = 0; i < count; i++)
+                {
+                    var prop:String = properties[i];
+                    encodeValue(element, obj[prop], context);
+                }
+            }
+        }
+
+        xml.appendChild(element);
+    }
+
+    private static function encodeString(xml:XML, str:String, 
context:AMFXContext, isTrait:Boolean = false):void
+    {
+        var ref:int = context.findString(str);
+        var element:XML = <string />;
+        if (ref >= 0)
+        {
+            element.@["id"] = String(ref);
+        }
+        else
+        {
+            //Remember string
+            context.addString(str);
+
+            if (str.length > 0)
+            {
+                // Traits won't contain chars that need escaping
+                if (!isTrait)
+                    str = escapeXMLString(str);
+
+                var x:XML = new XML(str);
+                element.appendChild(x);
+            }
+        }
+        xml.appendChild(element);
+    }
+
+    private static function encodeTraits(xml:XML, classInfo:Object, 
context:AMFXContext):void
+    {
+        var element:XML = <traits />;
+
+        var ref:int = context.findTraitInfo(classInfo);
+        if (ref >= 0)
+        {
+            element.@["id"] = String(ref);
+        }
+        else
+        {
+            //Remember trait info
+            context.addTraitInfo(classInfo)
+
+            if (classInfo.externalizable)
+            {
+                element.@["externalizable"] = "true";
+            }
+            else
+            {
+                var properties:Array = classInfo.properties;
+                if (properties != null)
+                {
+                    var count:uint = properties.length;
+                    for (var i:uint = 0; i < count; i++)
+                    {
+                        var prop:String = properties[i];
+                        encodeString(element, prop, context, true);
+                    }
+                }
+            }
+        }
+
+        xml.appendChild(element);
+    }
+
+    private static function encodeXML(xml:XML, xmlObject:Object):void
+    {
+        var element:XML = <xml />;
+        var str:String;
+        if (xmlObject is XML)
+            str = XML(xmlObject).toXMLString();
+        else
+            str = xmlObject.toString();
+
+        if (str.length > 0)
+        {
+            str = escapeXMLString(str);
+            var x:XML = new XML(str);
+            element.appendChild(x);
+        }
+        xml.appendChild(element);
+    }
+
+    private static function escapeXMLString(str:String):String
+    {
+        if (str.length > 0)
+        {
+            if ((str.indexOf("<") != -1) || (str.indexOf("&") != -1))
+            {
+                if (str.indexOf("]]>") != -1)
+                {
+                    str = str.replace(REGEX_CLOSE_CDATA, "]]&gt;");
+                }
+
+                str = "<![CDATA[" + str + "]]>";
+            }
+        }
+
+        return str;
+    }
+
+    private var settings:Object;
+
+    public static const CURRENT_VERSION:uint = 3;
+    public static const NAMESPACE_URI:String = 
"http://www.macromedia.com/2005/amfx";;
+    public static const NAMESPACE:Namespace = new Namespace("", NAMESPACE_URI);
+
+    private static const REGEX_CLASSNAME:RegExp = new RegExp("\\:\\:", "g");
+    private static const REGEX_CLOSE_CDATA:RegExp = new RegExp("]]>", "g");
+
+    private static const CLASS_INFO_OPTIONS:Object = {includeReadOnly:false, 
includeTransient:false};
+
+    private static const X_FALSE:XML = <false />;
+    private static const X_NULL:XML = <null />;
+    private static const X_TRUE:XML = <true />;
+    private static const X_UNDEFINED:XML = <undefined />;
+}
+
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXHeader.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXHeader.as
new file mode 100644
index 0000000..8cbbb86
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXHeader.as
@@ -0,0 +1,45 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.messaging.channels.amfx
+{
+
+[ExcludeClass]
+
+/**
+ * An AMFX request or response packet can contain headers.
+ *
+ * A Header must have a name, can be marked with a mustUnderstand
+ * boolean flag (the default is false), and the content can be any
+ * Object.
+ * @private
+ */
+public class AMFXHeader
+{
+    public var name:String;
+    public var mustUnderstand:Boolean;
+    public var content:Object;
+
+    public function AMFXHeader()
+    {
+        super();
+    }
+}
+
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXResult.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXResult.as
new file mode 100644
index 0000000..9902c93
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/channels/amfx/AMFXResult.as
@@ -0,0 +1,41 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.messaging.channels.amfx
+{
+
+[ExcludeClass]
+
+/**
+ * A simple context to hold the result of an AMFX request.
+ * @private
+ */
+public class AMFXResult
+{
+    public var version:uint;
+    public var headers:Array;
+    public var result:Object;
+
+    public function AMFXResult()
+    {
+        super();
+    }
+}
+
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/config/ServerConfig.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/config/ServerConfig.as
index 2f60e3c..54afb04 100644
--- 
a/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/config/ServerConfig.as
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/config/ServerConfig.as
@@ -383,6 +383,8 @@ public class ServerConfig
                 endpoint = channelConfig.endpoint;
                 // uri might be undefined when client-load-balancing urls are 
specified.
                 dsUri = endpoint.length() > 0? 
endpoint[0].attribute(URI_ATTR).toString() : null;
+                if (!dsUri)
+                    dsUri = endpoint.length() > 0? 
endpoint[0].attribute("url").toString() : null;
                 if (dsUri != null)
                     dsUris.push(dsUri);
             }
@@ -569,16 +571,24 @@ public class ServerConfig
         var channels:XMLList = xml.channels.channel.(@id == channelId);
         if (channels.length() == 0)
         {
-            message = resourceManager.getString(
-                "messaging", "unknownChannelWithId", [ channelId ]);
-            throw new InvalidChannelError(message);
+            channels = xml.channels["channel-definition"].(@id == channelId);
+            if (channels.length() == 0)
+            {
+                message = resourceManager.getString(
+                    "messaging", "unknownChannelWithId", [ channelId ]);
+                throw new InvalidChannelError(message);
+            }
         }
 
         var channelConfig:XML = channels[0];
         var className:String = channelConfig.attribute(CLASS_ATTR).toString();
+        if (!className)
+            className = channelConfig.attribute("class").toString();
         var endpoint:XMLList = channelConfig.endpoint;
         /// uri might be undefined when client-load-balancing urls are 
specified.
         var uri:String = endpoint.length() > 0? 
endpoint[0].attribute(URI_ATTR).toString() : null;
+        if (!uri)
+            uri = endpoint.length() > 0? 
endpoint[0].attribute("url").toString() : null;
         var channel:Channel = null;
         try
         {
@@ -652,6 +662,9 @@ public class ServerConfig
         }
     }
 
+    /**
+     * @royaleignorecoercion XML
+     */
     private static function getChannelIds(destinationConfig:XML):Array
     {
         var result:Array = [];
@@ -661,6 +674,15 @@ public class ServerConfig
         {
             result.push(channels[i][email protected]());
         }
+        if (n == 0)
+        {
+            channels = (destinationConfig.parent() as 
XML)["default-channels"].channel;
+            n = channels.length();
+            for (i = 0; i < n; i++)
+            {
+                result.push(channels[i][email protected]());
+            }
+        }
         return result;
     }
 
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/net/URLLoader.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/net/URLLoader.as
index ad03b3f..08b85a5 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/net/URLLoader.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/net/URLLoader.as
@@ -74,6 +74,11 @@ package mx.net
                        }
                        return false;
                }
+        
+        public function close():void
+        {
+            
+        }
        }
        
 }
\ No newline at end of file
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/LoadEvent.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/LoadEvent.as
index 8f6a857..b92eb3b 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/LoadEvent.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/LoadEvent.as
@@ -22,7 +22,7 @@ package mx.rpc.soap
 
 import org.apache.royale.events.Event;
 import org.apache.royale.events.IRoyaleEvent;
-import flash.xml.XMLDocument;
+//import flash.xml.XMLDocument;
 import mx.rpc.events.WSDLLoadEvent;
 import mx.rpc.wsdl.WSDL;
 
@@ -71,7 +71,6 @@ public class LoadEvent extends WSDLLoadEvent
      *  @playerversion Flash 9
      *  @playerversion AIR 1.1
      *  @productversion Flex 3
-     */
     public function get document():XMLDocument
     {
         if (_document == null && xml != null)
@@ -86,6 +85,7 @@ public class LoadEvent extends WSDLLoadEvent
         }
         return _document;
     }
+     */
 
     /**
      * Returns a copy of this LoadEvent.
@@ -150,7 +150,7 @@ public class LoadEvent extends WSDLLoadEvent
     */    
     public static const LOAD:String = "load";
 
-    private var _document:XMLDocument;
+    //private var _document:XMLDocument;
 }
 
 }
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/Operation.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/Operation.as
index 6243d69..45638dd 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/Operation.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/Operation.as
@@ -20,12 +20,9 @@
 package mx.rpc.soap
 {
 
-import org.apache.royale.events.Event;
-import flash.xml.XMLNode;
-
 import mx.core.mx_internal;
-import mx.logging.Log;
 import mx.logging.ILogger;
+import mx.logging.Log;
 import mx.messaging.ChannelSet;
 import mx.messaging.events.MessageEvent;
 import mx.messaging.events.MessageFaultEvent;
@@ -47,6 +44,8 @@ import mx.rpc.xml.SchemaConstants;
 import mx.utils.ObjectProxy;
 import mx.utils.XMLUtil;
 
+import org.apache.royale.events.Event;
+
 use namespace mx_internal;
 
 /**
@@ -61,7 +60,7 @@ use namespace mx_internal;
  */
 [Event(name="header", type="mx.rpc.events.HeaderEvent")]
 
-[ResourceBundle("rpc")]
+//[ResourceBundle("rpc")]
 
 /**
  * An Operation used specifically by WebServices. An Operation is an individual
@@ -787,7 +786,7 @@ public class Operation extends AbstractOperation
         var argsToPass:Object = null;
         if (args && args.length > 0)
         {
-            if ((args.length == 1) && (args[0] is XMLNode || args[0] is XML))
+            if ((args.length == 1) && (/*args[0] is XMLNode ||*/ args[0] is 
XML))
             {
                 // special case: handle xml node as single argument and drop
                 // into literal mode.
@@ -902,18 +901,24 @@ public class Operation extends AbstractOperation
         {
             soap = encoder.encodeRequest(pc.args, pc.headers);
         }
-        catch(fault:Fault)
+        catch(obj:Object)
         {
-            dispatchRpcEvent(FaultEvent.createEvent(fault));
-            return;
-        }
-        catch(error:Error)
-        {
-            var errorMsg:String = error.message ? error.message : "";
-            var fault2:Fault = new Fault("EncodingError", errorMsg);
-            var faultEvent:FaultEvent = FaultEvent.createEvent(fault2);
-            dispatchRpcEvent(faultEvent);
-            return;
+            if (obj is Fault)
+            {
+                var fault:Fault = obj as Fault;
+                dispatchRpcEvent(FaultEvent.createEvent(fault));
+                return;
+            }
+            else if (obj is Error)
+            {
+                var error:Error = obj as Error;
+                var errorMsg:String = error.message ? error.message : "";
+                var fault2:Fault = new Fault("EncodingError", errorMsg);
+                var faultEvent:FaultEvent = FaultEvent.createEvent(fault2);
+                dispatchRpcEvent(faultEvent);                
+                return;
+            }
+            throw obj;
         }
 
         message.httpHeaders = httpHeaders;
@@ -1007,20 +1012,26 @@ public class Operation extends AbstractOperation
             if (eventDispatchRequired)
                 _result = soapResult.result;
         }
-        catch (fault:Fault)
+        catch(obj:Object)
         {
-            fault.content = body;
-            dispatchRpcEvent(FaultEvent.createEvent(fault, token, message));
-            eventDispatchRequired = false;
-        }
-        catch (error:Error)
-        {
-            var errorMsg:String = error.message != null ? error.message : "";
-            var fault2:Fault = new Fault("DecodingError", errorMsg);
-            fault2.content = body;
-            var faultEvent:FaultEvent = FaultEvent.createEvent(fault2, token, 
message);
-            dispatchRpcEvent(faultEvent);
-            eventDispatchRequired = false;
+            if (obj is Fault)
+            {
+                var fault:Fault = obj as Fault;
+                fault.content = body;
+                dispatchRpcEvent(FaultEvent.createEvent(fault, token, 
message));
+                eventDispatchRequired = false;
+            }
+            else if (obj is Error)
+            {
+                var error:Error = obj as Error;
+                var errorMsg:String = error.message != null ? error.message : 
"";
+                var fault2:Fault = new Fault("DecodingError", errorMsg);
+                fault2.content = body;
+                var faultEvent:FaultEvent = FaultEvent.createEvent(fault2, 
token, message);
+                dispatchRpcEvent(faultEvent);
+                eventDispatchRequired = false;
+            }
+            else throw obj;
         }
 
         return eventDispatchRequired;
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPDecoder.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPDecoder.as
index 77aa7f6..33cd86b 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPDecoder.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPDecoder.as
@@ -20,9 +20,11 @@
 package mx.rpc.soap
 {
 
+/*
 import flash.utils.getTimer;
 import flash.xml.XMLDocument;
 import flash.xml.XMLNode;
+*/
 
 import mx.logging.ILogger;
 import mx.logging.Log;
@@ -228,7 +230,15 @@ public class SOAPDecoder extends XMLDecoder implements 
ISOAPDecoder
         else
             responseString = String(response);
 
-        var startTime:int = getTimer();
+        var startTime:Number;
+        COMPILE::SWF
+        {
+            startTime = new Date().time;
+        }
+        COMPILE::JS
+        {
+            startTime = Date.now();
+        }
 
         log.info("Decoding SOAP response");
 
@@ -261,7 +271,16 @@ public class SOAPDecoder extends XMLDecoder implements 
ISOAPDecoder
             }
         }
 
-        log.info("Decoded SOAP response into result [{0} millis]", getTimer() 
- startTime);
+        var stopTime:Number;
+        COMPILE::SWF
+        {
+            stopTime = new Date().time;
+        }
+        COMPILE::JS
+        {
+            stopTime = Date.now();
+        }
+        log.info("Decoded SOAP response into result [{0} millis]", stopTime - 
startTime);
         return soapResult;
     }
 
@@ -328,6 +347,7 @@ public class SOAPDecoder extends XMLDecoder implements 
ISOAPDecoder
                          // Return the children as an XMLList.
                         soapResult.result = bodyXML.children();
                     }
+                    /*
                     else if (resultFormat == "xml")
                     {
                          // Return the children as an Array of XMLNode
@@ -349,7 +369,7 @@ public class SOAPDecoder extends XMLDecoder implements 
ISOAPDecoder
                             }
                         }
                         soapResult.result = bodyArray;
-                    }
+                    }*/
                 }
             }
         }
@@ -718,10 +738,11 @@ public class SOAPDecoder extends XMLDecoder implements 
ISOAPDecoder
             {
                 headers.push(headerChild);
             }
+            /*
             else if (headerFormat == "xml")
             {
                 headers.push(new XMLDocument(headerChild.toString()));
-            }
+            }*/
         }
 
         return headers;
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPEncoder.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPEncoder.as
index bc2880e..dab1610 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPEncoder.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPEncoder.as
@@ -20,8 +20,8 @@
 package mx.rpc.soap
 {
 
-import flash.xml.XMLDocument;
-import flash.xml.XMLNode;
+//import flash.xml.XMLDocument;
+//import flash.xml.XMLNode;
 
 import mx.core.mx_internal;
 import mx.logging.ILogger;
@@ -40,7 +40,7 @@ import mx.rpc.xml.SchemaDatatypes;
 import mx.rpc.xml.SchemaMarshaller;
 import mx.rpc.xml.XMLEncoder;
 
-[ResourceBundle("rpc")]
+//[ResourceBundle("rpc")]
 
 [ExcludeClass]
 
@@ -679,6 +679,7 @@ public class SOAPEncoder extends XMLEncoder implements 
ISOAPEncoder
             {
                 preEncodedNode = value as XML;
             }
+            /*
             else if (value is XMLDocument)
             {
                 var xmlDocument:XMLDocument = value as XMLDocument;
@@ -689,6 +690,7 @@ public class SOAPEncoder extends XMLEncoder implements 
ISOAPEncoder
                 var xmlNode:XMLNode = value as XMLNode;
                 preEncodedNode = new XML(xmlNode.toString());
             }
+            */
         }
         return preEncodedNode;
     }
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPFault.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPFault.as
index 900abf3..ffa68da 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPFault.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/SOAPFault.as
@@ -20,7 +20,6 @@
 package mx.rpc.soap
 {
 
-import flash.xml.XMLNode;
 import mx.rpc.Fault;
 
 /**
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/WebService.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/WebService.as
index e506674..1f06eba 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/WebService.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/WebService.as
@@ -345,24 +345,31 @@ public dynamic class WebService extends AbstractWebService
 
             unEnqueueCalls();
         }
-        catch(fault:Fault)
+        catch(obj:Object)
         {
-            var faultEvent:FaultEvent = FaultEvent.createEvent(fault);
-            dispatchEvent(faultEvent);
-            super.unEnqueueCalls(fault); // Jump straight to fault handling; 
ops cannot be initialized.
-            return;
-        }
-        catch(error:Error)
-        {
-            var errorMessage:String = error.message ? error.message : ""; 
-                       var message:String =  /*resourceManager.getString(
-                               "rpc",*/ "unexpectedException" /*, [ 
errorMessage ])*/;          
-            var fault:Fault = new Fault("WSDLError", message);
-            fault.rootCause = error;
-            var faultEvent2:FaultEvent = FaultEvent.createEvent(fault);
-            dispatchEvent(faultEvent2);
-            super.unEnqueueCalls(fault); // Jump straight to fault handling; 
ops cannot be initialized.
-            return;
+            var fault:Fault;
+            if (obj is Fault)
+            {
+                fault = obj as Fault;
+                var faultEvent:FaultEvent = FaultEvent.createEvent(fault);
+                dispatchEvent(faultEvent);
+                super.unEnqueueCalls(fault); // Jump straight to fault 
handling; ops cannot be initialized.
+                return;
+            }
+            else if (obj is Error)
+            {
+                var error:Error = obj as Error;
+                var errorMessage:String = error.message ? error.message : ""; 
+                       var message:String =  /*resourceManager.getString(
+                               "rpc",*/ "unexpectedException" /*, [ 
errorMessage ])*/;          
+                fault = new Fault("WSDLError", message);
+                fault.rootCause = error;
+                var faultEvent2:FaultEvent = FaultEvent.createEvent(fault);
+                dispatchEvent(faultEvent2);
+                super.unEnqueueCalls(fault); // Jump straight to fault 
handling; ops cannot be initialized.
+                return;
+            }
+            throw obj;
         }
     }
 
@@ -377,7 +384,7 @@ public dynamic class WebService extends AbstractWebService
         if (destination)
             httpService.destination = destination;
         httpService.useProxy = useProxy;
-        httpService.resultFormat = HTTPService.RESULT_FORMAT_XML;
+        // httpService.resultFormat = HTTPService.RESULT_FORMAT_XML; AJH gets 
reset to E4X in XMLLoader
         httpService.rootURL = rootURL;
         httpService.headers = httpHeaders;
         return httpService;
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/mxml/Operation.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/mxml/Operation.as
index 4f44b48..11ff73a 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/mxml/Operation.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/mxml/Operation.as
@@ -200,7 +200,7 @@ public class Operation extends mx.rpc.soap.Operation 
implements IMXMLSupport
             return token;
         }
 
-        return super.send.apply(null, args);
+        return super.send.apply(this, args);
     }
 
 
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/mxml/WebService.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/mxml/WebService.as
index 56d6bd0..403f2a0 100644
--- 
a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/mxml/WebService.as
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/soap/mxml/WebService.as
@@ -23,9 +23,13 @@ package mx.rpc.soap.mxml
 import org.apache.royale.events.Event;
 import mx.events.ErrorEvent;
 import org.apache.royale.events.IEventDispatcher;
+import org.apache.royale.core.IDocument;
 
+import mx.core.IFlexModuleFactory;
 import mx.core.IMXMLObject;
+import mx.core.IUIComponent;
 import mx.core.mx_internal;
+import mx.managers.ISystemManager;
 import mx.resources.IResourceManager;
 import mx.resources.ResourceManager;
 import mx.rpc.AbstractOperation;
@@ -34,10 +38,11 @@ import mx.rpc.mxml.Concurrency;
 import mx.rpc.mxml.IMXMLSupport;
 import mx.rpc.soap.mxml.Operation;
 import mx.rpc.soap.WebService;
+import mx.messaging.config.ServerConfig;
 
 use namespace mx_internal;
 
-[ResourceBundle("rpc")]
+//[ResourceBundle("rpc")]
 
 /**
  * The &lt;mx:WebService&gt; tag gives you access to the operations of 
SOAP-compliant
@@ -94,7 +99,7 @@ use namespace mx_internal;
  *  @playerversion AIR 1.1
  *  @productversion Flex 3
  */
-public dynamic class WebService extends mx.rpc.soap.WebService implements 
IMXMLSupport, IMXMLObject
+public dynamic class WebService extends mx.rpc.soap.WebService implements 
IMXMLSupport, IMXMLObject, IDocument
 {
     
//--------------------------------------------------------------------------
     //
@@ -357,6 +362,26 @@ public dynamic class WebService extends 
mx.rpc.soap.WebService implements IMXMLS
         initialize();
     }
 
+    public function setDocument(document:Object, id:String = null):void
+    {
+        this.document = document;
+        this.id = id;
+        if (document is IEventDispatcher)
+        {
+            IEventDispatcher(document).addEventListener("creationComplete", 
creationComplete);
+        }
+        
+        COMPILE::JS
+        {
+            if (document is IUIComponent)    
+            {
+                ServerConfig.xml = new XML(((document as 
IUIComponent).systemManager as IFlexModuleFactory).info()["servicesConfig"]);
+            }
+                ;
+        }
+        
+        initialize();
+    }
 
     
//--------------------------------------------------------------------------
     //
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/wsdl/WSDL.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/wsdl/WSDL.as
index b83cd85..329ff8c 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/wsdl/WSDL.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/wsdl/WSDL.as
@@ -32,7 +32,7 @@ import mx.rpc.xml.SchemaConstants;
 import mx.rpc.xml.SchemaManager;
 import mx.rpc.xml.SchemaTypeRegistry;
 
-[ResourceBundle("rpc")]
+//[ResourceBundle("rpc")]
 
 [ExcludeClass]
 
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/wsdl/WSDLLoader.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/wsdl/WSDLLoader.as
index fa7fca4..5789bed 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/wsdl/WSDLLoader.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/rpc/wsdl/WSDLLoader.as
@@ -41,7 +41,7 @@ import mx.utils.URLUtil;
 [Event(name="fault", type="mx.rpc.events.FaultEvent")]
 [Event(name="wsdlLoad", type="mx.rpc.events.WSDLLoadEvent")]
 
-[ResourceBundle("rpc")]
+//[ResourceBundle("rpc")]
 
 [ExcludeClass]
 

Reply via email to