You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by al...@apache.org on 2018/05/14 07:25:23 UTC

[royale-asjs] branch feature/MXRoyale updated: ChannelSet.as Added

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

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


The following commit(s) were added to refs/heads/feature/MXRoyale by this push:
     new 83b84d1  ChannelSet.as Added
83b84d1 is described below

commit 83b84d132c59a1a3b688f89a46c84fdb1a704407
Author: alinakazi <AL...@GMAIL.COM>
AuthorDate: Mon May 14 00:25:21 2018 -0700

    ChannelSet.as Added
---
 .../src/main/royale/mx/messaging/ChannelSet.as     | 2157 ++++++++++++++++++++
 1 file changed, 2157 insertions(+)

diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/ChannelSet.as b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/ChannelSet.as
new file mode 100644
index 0000000..eb95791
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/messaging/ChannelSet.as
@@ -0,0 +1,2157 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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
+{
+
+/* import flash.errors.IllegalOperationError;
+import flash.events.EventDispatcher;
+import flash.events.TimerEvent;
+import flash.utils.Dictionary;
+import flash.utils.Timer;
+ */
+ import org.apache.royale.events.EventDispatcher;
+
+import mx.core.mx_internal;
+/* import mx.events.PropertyChangeEvent;
+import mx.messaging.channels.NetConnectionChannel;
+import mx.messaging.channels.PollingChannel;
+import mx.messaging.config.ServerConfig;
+import mx.messaging.errors.NoChannelAvailableError;
+import mx.messaging.events.ChannelEvent;
+import mx.messaging.events.ChannelFaultEvent;
+import mx.messaging.events.MessageEvent;
+import mx.messaging.events.MessageFaultEvent;
+import mx.messaging.messages.AcknowledgeMessage;
+import mx.messaging.messages.CommandMessage;
+import mx.messaging.messages.ErrorMessage;
+import mx.messaging.messages.IMessage;
+import mx.resources.IResourceManager;
+import mx.resources.ResourceManager;
+import mx.rpc.AsyncDispatcher;
+import mx.rpc.AsyncToken;
+import mx.rpc.events.AbstractEvent;
+import mx.rpc.events.FaultEvent;
+import mx.rpc.events.ResultEvent;
+import mx.utils.Base64Encoder;
+ */
+use namespace mx_internal;
+
+[DefaultProperty("channels")]
+
+/**
+ *  Dispatched after a Channel in the ChannelSet has connected to its endpoint.
+ *
+ *  @eventType mx.messaging.events.ChannelEvent.CONNECT
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion BlazeDS 4
+ *  @productversion LCDS 3
+ */
+//[Event(name="channelConnect", type="mx.messaging.events.ChannelEvent")]
+
+/**
+ *  Dispatched after a Channel in the ChannelSet has disconnected from its
+ *  endpoint.
+ *
+ *  @eventType mx.messaging.events.ChannelEvent.DISCONNECT
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion BlazeDS 4
+ *  @productversion LCDS 3
+ */
+//[Event(name="channelDisconnect", type="mx.messaging.events.ChannelEvent")]
+
+/**
+ *  Dispatched after a Channel in the ChannelSet has faulted.
+ *
+ *  @eventType mx.messaging.events.ChannelFaultEvent.FAULT
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion BlazeDS 4
+ *  @productversion LCDS 3
+ */
+//[Event(name="channelFault", type="mx.messaging.events.ChannelFaultEvent")]
+
+/**
+ * The result event is dispatched when a login or logout call successfully returns.
+ * @eventType mx.rpc.events.ResultEvent.RESULT
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion BlazeDS 4
+ *  @productversion LCDS 3
+ */
+//[Event(name="result", type="mx.rpc.events.ResultEvent")]
+
+/**
+ * The fault event is dispatched when a login or logout call fails.
+ * @eventType mx.rpc.events.FaultEvent.FAULT
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion BlazeDS 4
+ *  @productversion LCDS 3
+ */
+//[Event(name="fault", type="mx.rpc.events.FaultEvent")]
+
+/**
+ *  Dispatched when a property of the ChannelSet changes.
+ *
+ *  @eventType mx.events.PropertyChangeEvent.PROPERTY_CHANGE
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion BlazeDS 4
+ *  @productversion LCDS 3
+ */
+//[Event(name="propertyChange", type="mx.events.PropertyChangeEvent")]
+
+[ResourceBundle("messaging")]
+
+/**
+ *  The ChannelSet is a set of Channels that are used to send messages to a
+ *  target destination. The ChannelSet improves the quality of service on the
+ *  client by hunting through its Channels to send messages in the face of
+ *  network failures or individual Channel problems.
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion BlazeDS 4
+ *  @productversion LCDS 3
+ */
+public class ChannelSet extends EventDispatcher
+{
+    //--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Constructs a ChannelSet.
+     *  If the <code>channelIds</code> argument is provided, the ChannelSet will
+     *  use automatically configured Channels obtained via <code>ServerConfig.getChannel()</code>
+     *  to reach a destination.
+     *  Attempting to manually assign Channels to a ChannelSet that uses configured
+     *  Channels is not allowed.
+     *
+     *  <p>If the <code>channelIds</code> argument is not provided or is null,
+     *  Channels must be manually created and added to the ChannelSet in order
+     *  to connect and send messages.</p>
+     *
+     *  <p>If the ChannelSet is clustered using url-load-balancing (where each server
+     *  declares a unique RTMP or HTTP URL and the client fails over from one URL to
+     *  the next), the first time that a Channel in the ChannelSet successfully connects
+     *  the ChannelSet will automatically make a request for all of the endpoints across
+     *  the cluster for all member Channels and will assign these failover URLs to each
+     *  respective Channel.
+     *  This allows Channels in the ChannelSet to failover individually, and when failover
+     *  options for a specific Channel are exhausted the ChannelSet will advance to the next
+     *  Channel in the set to attempt to reconnect.</p>
+     *
+     *  <p>Regardless of clustering, if a Channel cannot connect or looses
+     *  connectivity, the ChannelSet will advance to its next available Channel
+     *  and attempt to reconnect.
+     *  This allows the ChannelSet to hunt through Channels that use different
+     *  protocols, ports, etc., in search of one that can connect to its endpoint
+     *  successfully.</p>
+     *
+     *  @param channelIds The ids of configured Channels obtained from ServerConfig for this ChannelSet to
+     *                    use. If null, Channels must be manually added to the ChannelSet.
+     *
+     *  @param clusteredWithURLLoadBalancing True if the Channels in the ChannelSet are clustered
+     *                   using url load balancing.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    public function ChannelSet(channelIds:Array = null, clusteredWithURLLoadBalancing:Boolean = false)
+    {
+        super();
+       /*  _clustered = clusteredWithURLLoadBalancing;
+        _connected = false;
+        _connecting = false;
+        _currentChannelIndex = -1;
+        if (channelIds != null)
+        {
+            _channelIds = channelIds;
+            _channels = new Array(_channelIds.length);
+            _configured = true;
+        }
+        else
+        {
+            _channels = [];
+            _configured = false;
+        }
+        _hasRequestedClusterEndpoints = false;
+        _hunting = false;
+        _messageAgents = [];
+        _pendingMessages = new Dictionary();
+        _pendingSends = [];
+        _shouldBeConnected = false;
+        _shouldHunt = true; */
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    // Variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Helper MessageAgent used for direct authentication.
+     */
+  //  private var _authAgent:AuthenticationAgent;
+
+    /**
+     *  @private
+     *  Flag indicating whether the ChannelSet is in the process of connecting
+     *  over the current Channel.
+     */
+   // private var _connecting:Boolean;
+
+    /**
+     *  @private
+     *  Stored credentials to be set on the member channels.
+     */
+   // private var _credentials:String;
+
+    /**
+     *  @private
+     *  The character-set encoding used to create the credentials String.
+     */
+  //  private var _credentialsCharset:String;
+
+    /**
+     *  @private
+     *  Current index into the _channels/_channelIds arrays.
+     */
+  //  private var _currentChannelIndex:int;
+
+    /**
+     *  @private
+     *  This flag restricts our cluster request to only happen upon initial
+     *  connect to the cluster.
+     */
+  //  private var _hasRequestedClusterEndpoints:Boolean;
+
+    /**
+     *  @private
+     *  Timer used to issue periodic heartbeats to the remote host if the
+     *  client is idle, and not actively sending messages.
+     */
+ //   private var _heartbeatTimer:Timer;
+
+    /**
+     *  @private
+     *  Flag indicating whether the ChannelSet is in the process of hunting to a
+     *  new Channel; this lets us control the "reconnecting" flag on
+     *  CONNECT ChannelEvents that we dispatch when we hunt to a new
+     *  Channel that isn't internally failing over. The new Channel doesn't know we're
+     *  in a reconnect attempt when it makes its initial connect attempt so this lets
+     *  us set "reconnecting" to true on the CONNECT event if it succeeds.
+     */
+ //   private var _hunting:Boolean;
+
+    /**
+     *  @private
+     *  A dictionary of pending messages used to filter out duplicate
+     *  messages passed to the ChannelSet to send while it is not connected.
+     *  This allows agents to perform message resend behavior (i.e. Consumer resubscribe
+     *  attempts) without worrying about duplicate messages queuing up and being sent to
+     *  the server once a connection is established.
+     */
+  //  private var _pendingMessages:Dictionary;
+
+    /**
+     *  @private
+     *  An array of PendingSend instances to pass into send() when a connection
+     *  is (re)established.
+     */
+   // private var _pendingSends:Array;
+
+    /**
+     *  @private
+     *  A timer used to do a delayed reconnect for NetConnection channels.
+     */
+   // private var _reconnectTimer:Timer = null;
+
+    /**
+     *  @private
+     *  Flag indicating whether the ChannelSet should be connected.
+     *  If true, the ChannelSet will attempt to hunt to the next available
+     *  Channel when a disconnect or fault occurs. If false, hunting is not
+     *  performed.
+     */
+  //  private var _shouldBeConnected:Boolean;
+
+    /**
+     *  @private
+     *  Flag indicating whether a Channel disconnect/fault should trigger hunting or not;
+     *  used when connected Channels are removed from the ChannelSet which should not trigger
+     *  hunting.
+     */
+  //  private var _shouldHunt:Boolean;
+
+    /**
+     *  @private
+     */
+  //  private var resourceManager:IResourceManager =
+   //                                 ResourceManager.getInstance();
+
+    //--------------------------------------------------------------------------
+    //
+    // Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  authenticated
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+   // private var _authenticated:Boolean;
+
+  //  [Bindable(event="propertyChange")]
+    /**
+     *  Indicates whether the ChannelSet has an underlying Channel that successfully
+     *  authenticated with its endpoint.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+   /*  public function get authenticated():Boolean
+    {
+        return _authenticated;
+    } */
+
+    /**
+     *  @private
+     */
+    /* mx_internal function setAuthenticated(value:Boolean, creds:String, notifyAgents:Boolean=true):void
+    {
+        if (_authenticated != value)
+        {
+            var event:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, "authenticated", _authenticated, value);
+            _authenticated = value;
+
+            if (notifyAgents)
+            {
+                var ma:MessageAgent;
+                for (var i:int = 0; i < _messageAgents.length; i++)
+                {
+                    ma = MessageAgent(_messageAgents[i]);
+                    ma.setAuthenticated(value, creds);
+                }
+            }
+
+            if (!value && _authAgent != null)
+                _authAgent.state = AuthenticationAgent.LOGGED_OUT_STATE;
+
+            dispatchEvent(event);
+        }
+    } */
+
+    //----------------------------------
+    //  channels
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+   // private var _channels:Array;
+
+    /**
+     *  Provides access to the Channels in the ChannelSet.
+     *  This property may be used to assign a set of channels at once or channels
+     *  may be added directly to the ChannelSet via addChannel() individually.
+     *  If this ChannelSet is <code>configured</code> automatically the individual
+     *  channels are created lazily and added to this property as needed.
+     *
+     *  @throws flash.errors.IllegalOperationError If the ChannelSet is
+     *             <code>configured</code>, assigning to this property is not allowed.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function get channels():Array
+    {
+        return _channels;
+    } 
+
+    [ArrayElementType("mx.messaging.Channel")]*/
+    /**
+     *  @private
+     */
+   /*  public function set channels(values:Array):void
+    {
+        if (configured)
+        {
+            var message:String = resourceManager.getString(
+                "messaging", "cannotAddWhenConfigured");
+            throw new IllegalOperationError(message);
+        }
+
+        // Remove existing channels
+        var channelsToRemove:Array = _channels.slice();
+        var n:int = channelsToRemove.length;
+        for (var i:int = 0; i < n; i++)
+        {
+            removeChannel(channelsToRemove[i]);
+        }
+
+        // Add new channels
+        if (values != null && values.length > 0)
+        {
+            var m:int = values.length;
+            for (var j:int = 0; j < m; j++)
+            {
+                addChannel(values[j]);
+            }
+        }
+    }
+ */
+    //----------------------------------
+    //  channelIds
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    //private var _channelIds:Array;
+
+    /**
+     *  The ids of the Channels used by the ChannelSet.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function get channelIds():Array
+    {
+        if (_channelIds != null)
+        {
+            return _channelIds;
+        }
+        else
+        {
+            var ids:Array = [];
+            var n:int = _channels.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                if (_channels[i] != null)
+                    ids.push(_channels[i].id);
+                else
+                    ids.push(null);
+            }
+            return ids;
+        }
+    } */
+
+    //----------------------------------
+    //  currentChannel
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    //private var _currentChannel:Channel;
+
+    /**
+     *  Returns the current Channel for the ChannelSet.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function get currentChannel():Channel
+    {
+        return _currentChannel;
+    } */
+
+    //----------------------------------
+    //  channelFailoverURIs
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    //private var _channelFailoverURIs:Object;
+
+    /**
+     *  @private
+     *  Map of arrays of failoverURIs keyed by channel id for the Channels in this ChannelSet.
+     *  This property is assigned to by the ClusterMessageResponder in order to update the
+     *  member Channels with their failoverURIs.
+     */
+    /* mx_internal function get channelFailoverURIs():Object
+    {
+        return _channelFailoverURIs;
+    } */
+
+    /**
+     *  @private
+     */
+    /* mx_internal function set channelFailoverURIs(value:Object):void
+    {
+        _channelFailoverURIs = value;
+        // Update any existing Channels in the set with their current failover endpoint URIs.
+        var n:int = _channels.length;
+        for (var i:int = 0; i < n; i++)
+        {
+            var channel:Channel = _channels[i];
+            if (channel == null)
+            {
+                break; // The rest of the Channels have not been loaded yet.
+            }
+            else if (_channelFailoverURIs[channel.id] != null)
+            {
+                channel.failoverURIs = _channelFailoverURIs[channel.id];
+            }
+        }
+    } */
+
+    //----------------------------------
+    //  configured
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    //private var _configured:Boolean;
+
+    /**
+     *  Indicates whether the ChannelSet is using automatically configured
+     *  Channels or manually assigned Channels.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* mx_internal function get configured():Boolean
+    {
+        return _configured;
+    } */
+
+    //----------------------------------
+    //  connected
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+   /*  private var _connected:Boolean;
+
+    [Bindable(event="propertyChange")] */
+    /**
+     *  Indicates whether the ChannelSet is connected.
+     */
+    /* public function get connected():Boolean
+    {
+        return _connected;
+    } */
+
+    /**
+     *  @private
+     */
+     // protected function setConnected(value:Boolean):void
+    // {
+        // if (_connected != value)
+        // {
+            // var event:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, "connected", _connected, value)
+            // _connected = value;
+            // dispatchEvent(event);
+            // setAuthenticated(value && currentChannel && currentChannel.authenticated, _credentials, false /* Agents also listen for channel disconnects */);
+            // if (!connected)
+            // {
+                // unscheduleHeartbeat();
+            // }
+            // else if (heartbeatInterval > 0)
+            // {
+                // scheduleHeartbeat();
+            // }
+        // }
+    // } 
+
+    //----------------------------------
+    //  clustered
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    //private var _clustered:Boolean;
+
+    /**
+     *  Indicates whether the ChannelSet targets a clustered destination.
+     *  If true, upon a successful connection the ChannelSet will query the
+     *  destination for all clustered endpoints for its Channels and will assign
+     *  failoverURIs to them.
+     *  Channel ids are used to assign failoverURIs to the proper Channel instances
+     *  so this requires that all Channels in the ChannelSet have non-null ids and an
+     *  Error will be thrown when this property is set to true if this is not the case.
+     *  If the ChannelSet is not using url load balancing on the client this
+     *  property should not be set to true.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function get clustered():Boolean
+    {
+        return _clustered;
+    } */
+
+    /**
+     *  @private
+     */
+    /* public function set clustered(value:Boolean):void
+    {
+        if (_clustered != value)
+        {
+            if (value)
+            {
+                // Cannot have a clustered ChannelSet that contains Channels with null ids.
+                var ids:Array = channelIds;
+                var n:int = ids.length;
+                for (var i:int = 0; i < n; i++)
+                {
+                    if (ids[i] == null)
+                    {
+                        var message:String = resourceManager.getString(
+                            "messaging", "cannotSetClusteredWithdNullChannelIds");
+                        throw new IllegalOperationError(message);
+                    }
+                }
+            }
+            _clustered = value;
+        }
+    } */
+
+    //----------------------------------
+    //  heartbeatInterval
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    //private var _heartbeatInterval:int = 0;
+
+    /**
+     *  The number of milliseconds between heartbeats sent to the remote
+     *  host while this ChannelSet is actively connected but idle.
+     *  Any outbound message traffic will delay heartbeats temporarily, with
+     *  this number of milliseconds elapsing after the last sent message before
+     *  the next heartbeat is issued.
+     *  <p>
+     *  This property is useful for applications that connect to a remote host
+     *  to received pushed updates and are not actively sending any messages, but
+     *  still wish to be notified of a dropped connection even when the networking
+     *  layer fails to provide such notification directly. By issuing periodic
+     *  heartbeats the client can force the networking layer to report a timeout
+     *  if the underlying connection has dropped without notification and the
+     *  application can respond to the disconnect appropriately.
+     *  </p>
+     *  <p>
+     *  Any non-positive value disables heartbeats to the remote host.
+     *  The default value is 0 indicating that heartbeats are disabled.
+     *  If the application sets this value it should prefer a longer rather than
+     *  shorter interval, to avoid placing unnecessary load on the remote host.
+     *  As an illustrative example, low-level TCP socket keep-alives generally
+     *  default to an interval of 2 hours. That is a longer interval than most
+     *  applications that enable heartbeats will likely want to use, but it
+     *  serves as a clear precedent to prefer a longer interval over a shorter
+     *  interval.
+     *  </p>
+     *  <p>
+     *  If the currently connected underlying Channel issues poll requests to
+     *  the remote host, heartbeats are suppressed because the periodic poll
+     *  requests effectively take their place.</p>
+     */
+    /* public function get heartbeatInterval():int
+    {
+        return _heartbeatInterval;
+    } */
+
+    /**
+     *  @private
+     */
+    /* public function set heartbeatInterval(value:int):void
+    {
+        if (_heartbeatInterval != value)
+        {
+            var event:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, "heartbeatInterval", _heartbeatInterval, value);
+            _heartbeatInterval = value;
+            dispatchEvent(event);
+            if (_heartbeatInterval > 0 && connected)
+            {
+                scheduleHeartbeat();
+            }
+        }
+    } */
+
+    //----------------------------------
+    //  initialDestinationId
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    //private var _initialDestinationId:String;
+
+    /**
+     *  Provides access to the initial destination this ChannelSet is used to access.
+     *  When the clustered property is true, this value is used to request available failover URIs
+     *  for the configured channels for the destination.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function get initialDestinationId():String
+    {
+        return _initialDestinationId;
+    }
+	*/
+    /**
+     *  @private
+     */
+    /* public function set initialDestinationId(value:String):void
+    {
+        _initialDestinationId = value;
+    } */
+
+    //----------------------------------
+    //  messageAgents
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    //private var _messageAgents:Array;
+
+    /**
+     *  Provides access to the set of MessageAgents that use this ChannelSet.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function get messageAgents():Array
+    {
+        return _messageAgents;
+    } */
+
+    //--------------------------------------------------------------------------
+    //
+    // Overridden Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Returns a String containing the ids of the Channels in the ChannelSet.
+     *
+     *  @return String representation of the ChannelSet.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* override public function toString():String
+    {
+        var s:String = "[ChannelSet ";
+        for (var i:uint = 0; i < _channels.length; i++)
+        {
+            if (_channels[i] != null)
+                s += _channels[i].id + " ";
+        }
+        s += "]";
+        return s;
+    } */
+
+    //--------------------------------------------------------------------------
+    //
+    // Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Adds a Channel to the ChannelSet. A Channel with a null id cannot be added
+     *  to the ChannelSet if the ChannelSet targets a clustered destination.
+     *
+     *  @param channel The Channel to add.
+     *
+     *  @throws flash.errors.IllegalOperationError If the ChannelSet is
+     *             <code>configured</code>, adding a Channel is not supported.
+     *             This error is also thrown if the ChannelSet's <code>clustered</code> property
+     *             is <code>true</code> but the Channel has a null id.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    public function addChannel(channel:Object):void //channel:Channel
+    {
+        /* if (channel == null)
+            return;
+
+        var message:String;
+
+        if (configured)
+        {
+            message = resourceManager.getString(
+                "messaging", "cannotAddWhenConfigured");
+            throw new IllegalOperationError(message);
+        }
+
+        if (clustered && channel.id == null)
+        {
+            message = resourceManager.getString(
+                "messaging", "cannotAddNullIdChannelWhenClustered");
+            throw new IllegalOperationError(message);
+        }
+
+        if (_channels.indexOf(channel) != -1)
+            return; // Channel already exists in the set.
+
+        _channels.push(channel);
+        if (_credentials)
+            channel.setCredentials(_credentials, null, _credentialsCharset); */
+    }
+
+    /**
+     *  Removes a Channel from the ChannelSet. If the Channel to remove is
+     *  currently connected and being used by the ChannelSet, it is
+     *  disconnected as well as removed.
+     *
+     *  @param channel The Channel to remove.
+     *
+     *  @throws flash.errors.IllegalOperationError If the ChannelSet is
+     *             <code>configured</code>, removing a Channel is not supported.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function removeChannel(channel:Channel):void
+    {
+        if (configured)
+        {
+            var message:String = resourceManager.getString(
+                "messaging", "cannotRemoveWhenConfigured");
+            throw new IllegalOperationError(message);
+        }
+
+        var channelIndex:int = _channels.indexOf(channel);
+        if (channelIndex > -1)
+        {
+            _channels.splice(channelIndex, 1);
+            // If the Channel being removed is currently in use, we need
+            // to null it out for re-hunting, and potentially disconnect it.
+            if ((_currentChannel != null) && (_currentChannel == channel))
+            {
+                if (connected)
+                {
+                    _shouldHunt = false;
+                    disconnectChannel();
+                }
+                _currentChannel = null;
+                _currentChannelIndex = -1;
+            }
+        }
+    } */
+
+    /**
+     *  Connects a MessageAgent to the ChannelSet. Once connected, the agent
+     *  can use the ChannelSet to send messages.
+     *
+     *  @param agent The MessageAgent to connect.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function connect(agent:MessageAgent):void
+    {
+        if ((agent != null) && (_messageAgents.indexOf(agent) == -1))
+        {
+            _shouldBeConnected = true;
+            _messageAgents.push(agent);
+            agent.internalSetChannelSet(this);
+            // Wire up agent's channel event listeners to this ChannelSet.
+            addEventListener(ChannelEvent.CONNECT, agent.channelConnectHandler);
+            addEventListener(ChannelEvent.DISCONNECT, agent.channelDisconnectHandler);
+            addEventListener(ChannelFaultEvent.FAULT, agent.channelFaultHandler);
+
+            // If the ChannelSet is already connected, notify the agent.
+            if (connected && !agent.needsConfig)
+                agent.channelConnectHandler(ChannelEvent.createEvent(ChannelEvent.CONNECT,
+                                                                     _currentChannel,
+                                                                     false,
+                                                                     false,
+                                                                     connected));
+        }
+    } */
+
+    /**
+     *  Disconnects a specific MessageAgent from the ChannelSet. If this is the
+     *  last MessageAgent using the ChannelSet and the current Channel in the set is
+     *  connected, the Channel will physically disconnect from the server.
+     *
+     *  @param agent The MessageAgent to disconnect.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function disconnect(agent:MessageAgent):void
+    {
+        if (agent == null) // Disconnect the ChannelSet completely.
+        {
+            var allMessageAgents:Array = _messageAgents.slice();
+            var n:int = allMessageAgents.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                allMessageAgents[i].disconnect();
+            }
+            if (_authAgent != null)
+            {
+                _authAgent.state = AuthenticationAgent.SHUTDOWN_STATE;
+                _authAgent = null;
+            }
+        }
+        else // Disconnect a specific MessageAgent.
+        {
+            var agentIndex:int = agent != null ? _messageAgents.indexOf(agent) : -1;
+            if (agentIndex != -1)
+            {
+                _messageAgents.splice(agentIndex, 1);
+                // Remove the agent as a listener to this ChannelSet.
+                removeEventListener(ChannelEvent.CONNECT, agent.channelConnectHandler);
+                removeEventListener(ChannelEvent.DISCONNECT, agent.channelDisconnectHandler);
+                removeEventListener(ChannelFaultEvent.FAULT, agent.channelFaultHandler);
+
+                if (connected || _connecting) // Notify the agent of the disconnect.
+                {
+                    agent.channelDisconnectHandler(ChannelEvent.createEvent(ChannelEvent.DISCONNECT,
+                                                                            _currentChannel, false));
+                }
+                else // Remove any pending sends for this agent.
+                {
+                    var n2:int = _pendingSends.length;
+                    for (var j:int = 0; j < n2; j++)
+                    {
+                        var ps:PendingSend = PendingSend(_pendingSends[j]);
+                        if (ps.agent == agent)
+                        {
+                            _pendingSends.splice(j, 1);
+                            j--;
+                            n2--;
+                            delete _pendingMessages[ps.message];
+                        }
+                    }
+                }
+                // Shut down the underlying Channel connection if this ChannelSet has
+                // no more agents using it.
+                if (_messageAgents.length == 0)
+                {
+                    _shouldBeConnected = false;
+                    _currentChannelIndex = -1;
+                    if (connected)
+                        disconnectChannel();
+                }
+
+                // Null out automatically assigned ChannelSet on agent; if manually assigned leave it alone.
+                if (agent.channelSetMode == MessageAgent.AUTO_CONFIGURED_CHANNELSET)
+                    agent.internalSetChannelSet(null);
+            }
+        }
+    } */
+
+    /**
+     *  Disconnects all associated MessageAgents and disconnects any underlying Channel that
+     *  is connected.
+     *  Unlike <code>disconnect(MessageAgent)</code> which is invoked by the disconnect implementations
+     *  of specific service components, this method provides a single, convenient point to shut down
+     *  connectivity between the client and server.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function disconnectAll():void
+    {
+        disconnect(null);
+    } */
+
+    /**
+     *  Handles a CONNECT ChannelEvent and redispatches the event.
+     *
+     *  @param event The ChannelEvent.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function channelConnectHandler(event:ChannelEvent):void
+    {
+        _connecting = false;
+        _connected = true; // Set internally to allow us to send pending messages before dispatching the connect event.
+        _currentChannelIndex = -1; // Reset index so that future disconnects are followed by hunting through all available options in order.
+
+        // Send any pending messages.
+        while (_pendingSends.length > 0)
+        {
+            var ps:PendingSend = PendingSend(_pendingSends.shift());
+            delete _pendingMessages[ps.message];
+
+            var command:CommandMessage = ps.message as CommandMessage;
+            if (command != null)
+            {
+                // Filter out any commands to trigger connection establishment, and ack them locally.
+                if (command.operation == CommandMessage.TRIGGER_CONNECT_OPERATION)
+                {
+                    var ack:AcknowledgeMessage = new AcknowledgeMessage();
+                    ack.clientId = ps.agent.clientId;
+                    ack.correlationId = command.messageId;
+                    ps.agent.acknowledge(ack, command);
+                    continue;
+                }
+
+                if (!ps.agent.configRequested && ps.agent.needsConfig &&
+                    (command.operation == CommandMessage.CLIENT_PING_OPERATION))
+                {
+                    command.headers[CommandMessage.NEEDS_CONFIG_HEADER] = true;
+                    ps.agent.configRequested = true;
+                }
+            }
+
+            send(ps.agent, ps.message);
+        }
+
+        if (_hunting)
+        {
+            event.reconnecting = true;
+            _hunting = false;
+        }
+
+        // Redispatch Channel connect event.
+        dispatchEvent(event);
+        // Dispatch delayed "connected" property change event.
+        var connectedChangeEvent:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, "connected", false, true)
+        dispatchEvent(connectedChangeEvent);
+    } */
+
+    /**
+     *  Handles a DISCONNECT ChannelEvent and redispatches the event.
+     *
+     *  @param event The ChannelEvent.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function channelDisconnectHandler(event:ChannelEvent):void
+    {
+        _connecting = false;
+        setConnected(false);
+
+        // If we should be connected and the Channel isn't failing over
+        // internally and wasn't rejected, hunt and try to reconnect.
+        if (_shouldBeConnected && !event.reconnecting && !event.rejected)
+        {
+            if (_shouldHunt && hunt())
+            {
+                event.reconnecting = true;
+                dispatchEvent(event);
+                if (_currentChannel is NetConnectionChannel)
+                {
+                    // Insert slight delay for reconnect to allow NetConnection
+                    // based channels to shut down and clean up in preparation
+                    // for our next connect attempt.
+                    if (_reconnectTimer == null)
+                    {
+                        _reconnectTimer = new Timer(1, 1);
+                        _reconnectTimer.addEventListener(TimerEvent.TIMER, reconnectChannel);
+                        _reconnectTimer.start();
+                    }
+                }
+                else // No need to wait with other channel types.
+                {
+                    connectChannel();
+                }
+            }
+            else // No more hunting options; give up and fault pending sends.
+            {
+                dispatchEvent(event);
+                faultPendingSends(event);
+            }
+        }
+        else
+        {
+            dispatchEvent(event);
+            // If the underlying Channel was rejected, fault pending sends.
+            if (event.rejected)
+                faultPendingSends(event);
+        }
+        // Flip this back to true in case it was turned off by an explicit Channel removal
+        // that triggered the current disconnect event.
+        _shouldHunt = true;
+    } */
+
+    /**
+     *  Handles a ChannelFaultEvent and redispatches the event.
+     *
+     *  @param event The ChannelFaultEvent.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function channelFaultHandler(event:ChannelFaultEvent):void
+    {
+        if (event.channel.connected)
+        {
+            dispatchEvent(event);
+        }
+        else // The channel fault has resulted in disconnecting.
+        {
+            _connecting = false;
+            setConnected(false);
+
+            // If we should be connected and the Channel isn't failing over
+            // internally, hunt and try to reconnect.
+            if (_shouldBeConnected && !event.reconnecting && !event.rejected)
+            {
+                if (hunt())
+                {
+                    event.reconnecting = true;
+                    dispatchEvent(event);
+                    if (_currentChannel is NetConnectionChannel)
+                    {
+                        // Insert slight delay for reconnect to allow
+                        // NetConnection based channels to shut down and clean
+                        // up in preparation for our next connect attempt.
+                        if (_reconnectTimer == null)
+                        {
+                            _reconnectTimer = new Timer(1, 1);
+                            _reconnectTimer.addEventListener(TimerEvent.TIMER, reconnectChannel);
+                            _reconnectTimer.start();
+                        }
+                    }
+                    else // No need to wait with other channel types.
+                    {
+                        connectChannel();
+                    }
+                }
+                else // No more hunting options; give up and fault pending sends.
+                {
+                    dispatchEvent(event);
+                    faultPendingSends(event);
+                }
+            }
+            else
+            {
+                dispatchEvent(event);
+                // If the underlying Channel was rejected, fault pending sends.
+                if (event.rejected)
+                    faultPendingSends(event);
+            }
+        }
+    } */
+
+    /**
+     *  Authenticates the ChannelSet with the server using the provided credentials.
+     *  Unlike other operations on Channels and the ChannelSet, this operation returns an
+     *  AsyncToken that client code may add a responder to in order to handle success or
+     *  failure directly.
+     *  If the ChannelSet is not connected to the server when this method is invoked it will
+     *  trigger a connect attempt, and if successful, send the login command to the server.
+     *  Only one login or logout operation may be pending at a time and overlapping calls will
+     *  generate an IllegalOperationError.
+     *  Invoking login when the ChannelSet is already authenticated will generate also generate
+     *  an IllegalOperationError.
+     *
+     *  @param username The username.
+     *  @param password The password.
+     *  @param charset The character set encoding to use while encoding the
+     *  credentials. The default is null, which implies the legacy charset of
+     *  ISO-Latin-1. The only other supported charset is &quot;UTF-8&quot;.
+     *
+     *  @return Returns a token that client code may add a responder to in order to handle
+     *  success or failure directly.
+     *
+     *  @throws flash.errors.IllegalOperationError in two situations; if the ChannelSet is
+     *          already authenticated, or if a login or logout operation is currently in progress.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function login(username:String, password:String, charset:String=null):AsyncToken
+    {
+        if (authenticated)
+            throw new IllegalOperationError("ChannelSet is already authenticated.");
+
+        if ((_authAgent != null) && (_authAgent.state != AuthenticationAgent.LOGGED_OUT_STATE))
+            throw new IllegalOperationError("ChannelSet is in the process of logging in or logging out.");
+
+        if (charset != Base64Encoder.CHARSET_UTF_8)
+            charset = null; // Use legacy charset, ISO-Latin-1.
+
+        var credentials:String = null;
+        if (username != null && password != null)
+        {
+            var rawCredentials:String = username + ":" + password;
+            var encoder:Base64Encoder = new Base64Encoder();
+            if (charset == Base64Encoder.CHARSET_UTF_8)
+                encoder.encodeUTFBytes(rawCredentials);
+            else
+                encoder.encode(rawCredentials);
+            credentials = encoder.drain();
+        }
+
+        var msg:CommandMessage = new CommandMessage();
+        msg.operation = CommandMessage.LOGIN_OPERATION;
+        msg.body = credentials;
+        if (charset != null)
+            msg.headers[CommandMessage.CREDENTIALS_CHARSET_HEADER] = charset;
+
+        // A non-null, non-empty destination is required to send using an agent.
+        // This value is ignored on the server and the message must be handled by an AuthenticationService.
+        msg.destination = "auth";
+
+        var token:AsyncToken = new AsyncToken(msg);
+        if (_authAgent == null)
+            _authAgent = new AuthenticationAgent(this);
+        _authAgent.registerToken(token);
+        _authAgent.state = AuthenticationAgent.LOGGING_IN_STATE;
+        send(_authAgent, msg);
+        return token;
+    } */
+
+    /**
+     *  Logs the ChannelSet out from the server. Unlike other operations on Channels
+     *  and the ChannelSet, this operation returns an AsyncToken that client code may
+     *  add a responder to in order to handle success or failure directly.
+     *  If logout is successful any credentials that have been cached for use in
+     *  automatic reconnects are cleared for the ChannelSet and its Channels and their
+     *  authenticated state is set to false.
+     *  If the ChannelSet is not connected to the server when this method is invoked it
+     *  will trigger a connect attempt, and if successful, send a logout command to the server.
+     *
+     *  <p>The MessageAgent argument is present to support legacy logout behavior and client code that
+     *  invokes this method should not pass a MessageAgent reference. Just invoke <code>logout()</code>
+     *  passing no arguments.</p>
+     *
+     *  <p>This method is also invoked by service components from their <code>logout()</code>
+     *  methods, and these components pass a MessageAgent reference to this method when they logout.
+     *  The presence of this argument is the trigger to execute legacy logout behavior that differs
+     *  from the new behavior described above.
+     *  Legacy behavior only sends a logout request to the server if the client is connected
+     *  and authenticated.
+     *  If these conditions are not met the legacy behavior for this method is to do nothing other
+     *  than clear any credentials that have been cached for use in automatic reconnects.</p>
+     *
+     *  @param agent Legacy argument. The MessageAgent that is initiating the logout.
+     *
+     *  @return Returns a token that client code may
+     *  add a responder to in order to handle success or failure directly.
+     *
+     *  @throws flash.errors.IllegalOperationError if a login or logout operation is currently in progress.
+     */
+    /* public function logout(agent:MessageAgent=null):AsyncToken
+    {
+        _credentials = null;
+        if (agent == null)
+        {
+            if ((_authAgent != null) && (_authAgent.state == AuthenticationAgent.LOGGING_OUT_STATE
+                                         || _authAgent.state == AuthenticationAgent.LOGGING_IN_STATE))
+                throw new IllegalOperationError("ChannelSet is in the process of logging in or logging out.");
+
+            // Clear out current credentials on the client.
+            var n:int = _messageAgents.length;
+            var i:int = 0;
+            for (; i < n; i++)
+            {
+                _messageAgents[i].internalSetCredentials(null);
+            }
+            n = _channels.length;
+            for (i = 0; i < n; i++)
+            {
+                if (_channels[i] != null)
+                {
+                    _channels[i].internalSetCredentials(null);
+                    if (_channels[i] is PollingChannel)
+                        PollingChannel(_channels[i]).disablePolling();
+                }
+            }
+
+            var msg:CommandMessage = new CommandMessage();
+            msg.operation = CommandMessage.LOGOUT_OPERATION;
+
+            // A non-null, non-empty destination is required to send using an agent.
+            // This value is ignored on the server and the message must be handled by an AuthenticationService.
+            msg.destination = "auth";
+
+            var token:AsyncToken = new AsyncToken(msg);
+            if (_authAgent == null)
+                _authAgent = new AuthenticationAgent(this);
+            _authAgent.registerToken(token);
+            _authAgent.state = AuthenticationAgent.LOGGING_OUT_STATE;
+            send(_authAgent, msg);
+            return token;
+        }
+        else // Legacy logout logic.
+        {
+            var n2:int = _channels.length;
+            for (var i2:int = 0; i2 < n2; i2++)
+            {
+                if (_channels[i2] != null)
+                    _channels[i2].logout(agent);
+            }
+            return null; // Legacy service logout() impls don't expect a token.
+        }
+    } */
+
+    /**
+     *  Sends a message from a MessageAgent over the currently connected Channel.
+     *
+     *  @param agent The MessageAgent sending the message.
+     *
+     *  @param message The Message to send.
+     *
+     *  @throws mx.messaging.errors.NoChannelAvailableError If the ChannelSet has no internal
+     *                                  Channels to use.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function send(agent:MessageAgent, message:IMessage):void
+    {
+        if (_currentChannel != null && _currentChannel.connected)
+        {
+            // Filter out any commands to trigger connection establishment, and
+            // ack them locally unless the agent needs config.
+            if ((message is CommandMessage && CommandMessage(message).operation == CommandMessage.TRIGGER_CONNECT_OPERATION)
+                && !agent.needsConfig)
+            {
+                var ack:AcknowledgeMessage = new AcknowledgeMessage();
+                ack.clientId = agent.clientId;
+                ack.correlationId = message.messageId;
+                new AsyncDispatcher(agent.acknowledge, [ack, message], 1);
+                return;
+            }
+
+            // If this ChannelSet targets a clustered destination, request the
+            // endpoint URIs for the cluster.
+            if (!_hasRequestedClusterEndpoints && clustered)
+            {
+                var msg:CommandMessage = new CommandMessage();
+                // Fetch failover URIs for the correct destination.
+                if (agent is AuthenticationAgent)
+                {
+                    msg.destination = initialDestinationId;
+                }
+                else
+                {
+                    msg.destination = agent.destination;
+                }
+                msg.operation = CommandMessage.CLUSTER_REQUEST_OPERATION;
+                _currentChannel.sendInternalMessage(new ClusterMessageResponder(msg, this));
+                _hasRequestedClusterEndpoints = true;
+            }
+            unscheduleHeartbeat();
+            _currentChannel.send(agent, message);
+            scheduleHeartbeat();
+        }
+        else
+        {
+            // Filter out duplicate messages here while waiting for the underlying Channel to connect.
+            if (_pendingMessages[message] == null)
+            {
+                _pendingMessages[message] = true;
+                _pendingSends.push(new PendingSend(agent, message));
+            }
+
+            if (!_connecting)
+            {
+                if ((_currentChannel == null) || (_currentChannelIndex == -1))
+                    hunt();
+
+                if (_currentChannel is NetConnectionChannel)
+                {
+                    // Insert a slight delay in case we've hunted to a
+                    // NetConnection channel that doesn't allow a reconnect
+                    // within the same frame as a disconnect.
+                    if (_reconnectTimer == null)
+                    {
+                        _reconnectTimer = new Timer(1, 1);
+                        _reconnectTimer.addEventListener(TimerEvent.TIMER, reconnectChannel);
+                        _reconnectTimer.start();
+                    }
+                }
+                else // No need to wait with other channel types.
+                {
+                    connectChannel();
+                }
+            }
+        }
+    } */
+
+    /**
+     *  Stores the credentials and passes them through to every connected channel.
+     *
+     *  @param credentials The credentials for the MessageAgent.
+     *  @param agent The MessageAgent that is setting the credentials.
+     *  @param charset The character set encoding used while encoding the
+     *  credentials. The default is null, which implies the legacy encoding of
+     *  ISO-Latin-1.
+     *
+     *  @throws flash.errors.IllegalOperationError in two situations; if credentials
+     *  have already been set and an authentication is in progress with the remote
+     *  detination, or if authenticated and the credentials specified don't match
+     *  the currently authenticated credentials.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function setCredentials(credentials:String, agent:MessageAgent, charset:String=null):void
+    {
+        _credentials = credentials;
+        var n:int = _channels.length;
+        for (var i:int = 0; i < n; i++)
+        {
+            if (_channels[i] != null)
+                _channels[i].setCredentials(_credentials, agent, charset);
+        }
+    } */
+
+    //--------------------------------------------------------------------------
+    //
+    // Internal Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Handles a successful login or logout operation for the ChannelSet.
+     */
+    /* mx_internal function authenticationSuccess(agent:AuthenticationAgent, token:AsyncToken, ackMessage:AcknowledgeMessage):void
+    {
+        // Reset authentication state depending on whether a login or logout was successful.
+        var command:CommandMessage = CommandMessage(token.message);
+        var handlingLogin:Boolean = (command.operation == CommandMessage.LOGIN_OPERATION);
+        var creds:String = (handlingLogin) ? String(command.body) : null;
+        var delay:Number = 0;
+
+        if (handlingLogin)
+        {
+            // First, sync everything with the current credentials.
+            _credentials = creds;
+            var n:int = _messageAgents.length;
+            var i:int = 0;
+            for (; i < n; i++)
+            {
+                _messageAgents[i].internalSetCredentials(creds);
+            }
+            n = _channels.length;
+            for (i = 0; i < n; i++)
+            {
+                if (_channels[i] != null)
+                    _channels[i].internalSetCredentials(creds);
+            }
+
+            agent.state = AuthenticationAgent.LOGGED_IN_STATE;
+            // Flip the currently connected channel to authenticated; this percolates
+            // back up through the ChannelSet and agent's authenticated properties.
+            currentChannel.setAuthenticated(true);
+        }
+        else // Logout.
+        {
+            // Shutdown the current logged out agent.
+            agent.state = AuthenticationAgent.SHUTDOWN_STATE;
+            _authAgent = null;
+            // Slight delay is used to make sure the disconnect message makes it
+            // to the server before result is dispatched to avoid duplicate session
+            // errors. See Watson 2780176 for details.
+            delay = 250;
+            disconnect(agent);
+
+            // Flip current channel to *not* authenticated; this percolates
+            // back up through the ChannelSet and agent's authenticated properties.
+            currentChannel.setAuthenticated(false);
+        }
+
+        // Notify.
+        var resultEvent:ResultEvent = ResultEvent.createEvent(ackMessage.body, token, ackMessage);
+        if (delay > 0)
+            new AsyncDispatcher(dispatchRPCEvent, [resultEvent], delay);
+        else
+            dispatchRPCEvent(resultEvent);
+    } */
+
+    /**
+     *  @private
+     *  Handles a failed login or logout operation for the ChannelSet.
+     */
+    /* mx_internal function authenticationFailure(agent:AuthenticationAgent, token:AsyncToken, faultMessage:ErrorMessage):void
+    {
+        var messageFaultEvent:MessageFaultEvent = MessageFaultEvent.createEvent(faultMessage);
+        var faultEvent:FaultEvent = FaultEvent.createEventFromMessageFault(messageFaultEvent, token);
+        // Leave the ChannelSet in its current auth state and dispose of the auth agent that failed.
+        agent.state = AuthenticationAgent.SHUTDOWN_STATE;
+        _authAgent = null;
+        disconnect(agent);
+        // And notify.
+        dispatchRPCEvent(faultEvent);
+    } */
+
+    //--------------------------------------------------------------------------
+    //
+    // Protected Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Helper method to fault pending messages.
+     *  The ErrorMessage is tagged with a __retryable__ header to indicate that
+     *  the error was due to connectivity problems on the client as opposed to
+     *  a server error response and the message can be retried (resent).
+     *
+     *  @param event A ChannelEvent.DISCONNECT or a ChannelFaultEvent that is the root cause
+     *               for faulting these pending sends.
+     */
+    /* protected function faultPendingSends(event:ChannelEvent):void
+    {
+        while (_pendingSends.length > 0)
+        {
+            var ps:PendingSend = _pendingSends.shift() as PendingSend;
+            var pendingMsg:IMessage = ps.message;
+            delete _pendingMessages[pendingMsg];
+            // Fault the message to its agent.
+            var errorMsg:ErrorMessage = new ErrorMessage();
+            errorMsg.correlationId = pendingMsg.messageId;
+            errorMsg.headers[ErrorMessage.RETRYABLE_HINT_HEADER] = true;
+            errorMsg.faultCode = "Client.Error.MessageSend";
+            errorMsg.faultString = resourceManager.getString(
+                "messaging", "sendFailed");
+            if (event is ChannelFaultEvent)
+            {
+                var faultEvent:ChannelFaultEvent = event as ChannelFaultEvent;
+                errorMsg.faultDetail = faultEvent.faultCode + " " +
+                                   faultEvent.faultString + " " +
+                                   faultEvent.faultDetail;
+                // This is to make streaming channels report authentication fault
+                // codes correctly as they don't report connected until streaming
+                // connection is established and hence end up here.
+                if (faultEvent.faultCode == "Channel.Authentication.Error")
+                    errorMsg.faultCode = faultEvent.faultCode;
+            }
+            // ChannelEvent.DISCONNECT is treated the same as never
+            // being able to connect at all.
+            else
+            {
+                errorMsg.faultDetail = resourceManager.getString(
+                    "messaging", "cannotConnectToDestination");
+            }
+            errorMsg.rootCause = event;
+            ps.agent.fault(errorMsg, pendingMsg);
+        }
+    } */
+
+    /**
+     *  Redispatches message events from the currently connected Channel.
+     *
+     *  @param event The MessageEvent from the Channel.
+     */
+    /* protected function messageHandler(event:MessageEvent):void
+    {
+        dispatchEvent(event);
+    } */
+
+    /**
+     *  @private
+     *  Schedules a heartbeat to be sent in heartbeatInterval milliseconds.
+     */
+    /* protected function scheduleHeartbeat():void
+    {
+        if (_heartbeatTimer == null && heartbeatInterval > 0)
+        {
+            _heartbeatTimer = new Timer(heartbeatInterval, 1);
+            _heartbeatTimer.addEventListener(TimerEvent.TIMER, sendHeartbeatHandler);
+            _heartbeatTimer.start();
+        }
+    } */
+
+    /**
+     *  @private
+     *  Handles a heartbeat timer event by conditionally sending a heartbeat
+     *  and scheduling the next.
+     */
+    /* protected function sendHeartbeatHandler(event:TimerEvent):void
+    {
+        unscheduleHeartbeat();
+        if (currentChannel != null)
+        {
+            sendHeartbeat();
+            scheduleHeartbeat();
+        }
+    } */
+
+    /**
+     *  @private
+     *  Sends a heartbeat request.
+     */
+    // protected function sendHeartbeat():void
+    // {
+        // //Current channel may be actively polling, which suppresses explicit heartbeats.
+        // var pollingChannel:PollingChannel = currentChannel as PollingChannel;
+        // if (pollingChannel != null && pollingChannel._shouldPoll) return;
+        // //Issue an explicit heartbeat and schedule the next.
+        // var heartbeat:CommandMessage = new CommandMessage();
+        // heartbeat.operation = CommandMessage.CLIENT_PING_OPERATION;
+        // heartbeat.headers[CommandMessage.HEARTBEAT_HEADER] = true;
+        // currentChannel.sendInternalMessage(new MessageResponder(null /* no agent */, heartbeat));
+    // }
+
+    /**
+     *  @private
+     *  Unschedules any currently scheduled pending heartbeat.
+     */
+    /* protected function unscheduleHeartbeat():void
+    {
+        if (_heartbeatTimer != null)
+        {
+            _heartbeatTimer.stop();
+            _heartbeatTimer.removeEventListener(TimerEvent.TIMER, sendHeartbeatHandler);
+            _heartbeatTimer = null;
+        }
+    } */
+
+    //--------------------------------------------------------------------------
+    //
+    // Private Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Helper method to connect the current internal Channel.
+     */
+    /* private function connectChannel():void
+    {
+        _connecting = true;
+        _currentChannel.connect(this);
+        // Listen for any server pushed messages on the Channel.
+        _currentChannel.addEventListener(MessageEvent.MESSAGE, messageHandler);
+    } */
+
+    /**
+     *  @private
+     *  Helper method to disconnect the current internal Channel.
+     */
+    /* private function disconnectChannel():void
+    {
+        _connecting = false;
+        // Stop listening for server pushed messages on the Channel.
+        _currentChannel.removeEventListener(MessageEvent.MESSAGE, messageHandler);
+        _currentChannel.disconnect(this);
+    } */
+
+    /**
+     *  @private
+     *  Helper method to dispatch authentication-related RPC events.
+     *
+     *  @param event The event to dispatch.
+     */
+    /* private function dispatchRPCEvent(event:AbstractEvent):void
+    {
+        event.callTokenResponders();
+        dispatchEvent(event);
+    } */
+
+    /**
+     *  @private
+     *  Helper method to hunt to the next available internal Channel for the
+     *  ChannelSet.
+     *
+     *  @return True if hunting to the next available Channel was successful; false if hunting
+     *          exhausted available channels and has reset to the beginning of the set.
+     *
+     *  @throws mx.messaging.errors.NoChannelAvailableError If the ChannelSet has no internal
+     *                                  Channels to use.
+     */
+    /* private function hunt():Boolean
+    {
+        if (_channels.length == 0)
+        {
+            var message:String = resourceManager.getString(
+                "messaging", "noAvailableChannels");
+            throw new NoChannelAvailableError(message);
+        }
+
+        // Unwire from the current channel.
+        if (_currentChannel != null)
+            disconnectChannel();
+
+        // Advance to next channel, and reset to beginning if all Channels in the set
+        // have been attempted.
+        if (++_currentChannelIndex >= _channels.length)
+        {
+            _currentChannelIndex = -1;
+            return false;
+        }
+
+        // If we've advanced past the first channel, indicate that we're hunting.
+        if (_currentChannelIndex > 0)
+            _hunting = true;
+
+        // Set current channel.
+        if (configured)
+        {
+            if (_channels[_currentChannelIndex] != null)
+            {
+                _currentChannel = _channels[_currentChannelIndex];
+            }
+            else
+            {
+                _currentChannel = ServerConfig.getChannel(_channelIds[
+                                        _currentChannelIndex], _clustered);
+                _currentChannel.setCredentials(_credentials);
+                _channels[_currentChannelIndex] = _currentChannel;
+            }
+        }
+        else
+        {
+            _currentChannel = _channels[_currentChannelIndex];
+        }
+
+        // Ensure that the current channel is assigned failover URIs it if was lazily instantiated.
+        if ((_channelFailoverURIs != null) && (_channelFailoverURIs[_currentChannel.id] != null))
+            _currentChannel.failoverURIs = _channelFailoverURIs[_currentChannel.id];
+
+        return true;
+    } */
+
+    /**
+     *  @private
+     *  This method is invoked by a timer and it works around a reconnect issue
+     *  with NetConnection based channels within a single frame by reconnecting after a slight delay.
+     */
+    /* private function reconnectChannel(event:TimerEvent):void
+    {
+        _reconnectTimer.stop();
+        _reconnectTimer.removeEventListener(TimerEvent.TIMER, reconnectChannel);
+        _reconnectTimer = null;
+        connectChannel();
+    } */
+}
+
+}
+
+//------------------------------------------------------------------------------
+//
+// Private Classes
+//
+//------------------------------------------------------------------------------
+
+/* import mx.core.mx_internal;
+import mx.logging.Log;
+import mx.messaging.ChannelSet;
+import mx.messaging.MessageAgent;
+import mx.messaging.MessageResponder;
+import mx.messaging.events.ChannelEvent;
+import mx.messaging.messages.IMessage;
+import mx.messaging.messages.AcknowledgeMessage;
+import mx.messaging.messages.CommandMessage;
+import mx.messaging.messages.ErrorMessage;
+import mx.rpc.AsyncToken;
+import mx.collections.ArrayCollection;
+
+use namespace mx_internal; */
+
+/**
+ *  @private
+ *  Clustered ChannelSets need to request the clustered channel endpoints for
+ *  the channels they contain upon a successful connect. However, Channels
+ *  require that all outbound messages be sent by a MessageAgent that their
+ *  internal MessageResponder implementations can callback to upon a response
+ *  or fault. The ChannelSet is not a MessageAgent, so in this case, it
+ *  circumvents the regular Channel.send() by passing its own custom responder
+ *  to Channel.sendUsingCustomResponder().
+ *
+ *  This is the custom responder.
+ */
+/* class ClusterMessageResponder extends MessageResponder
+{ */
+    //--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function ClusterMessageResponder(message:IMessage, channelSet:ChannelSet)
+    {
+        super(null, message);
+        _channelSet = channelSet;
+    } */
+
+    //--------------------------------------------------------------------------
+    //
+    // Variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Gives the responder access to this ChannelSet, to pass it failover URIs for
+     *  its channels.
+     */
+   // private var _channelSet:ChannelSet;
+
+    //--------------------------------------------------------------------------
+    //
+    // Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Handles a cluster message response.
+     *
+     *  @param message The response Message.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* override protected function resultHandler(message:IMessage):void
+    {
+        if ((message.body != null) && (message.body is Array || message.body is ArrayCollection))
+        {
+            var channelFailoverURIs:Object = {};
+            var mappings:Array = message.body is Array? message.body as Array : (message.body as ArrayCollection).toArray();
+            var n:int = mappings.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                var channelToEndpointMap:Object = mappings[i];
+                for (var channelId:Object in channelToEndpointMap)
+                {
+                    if (channelFailoverURIs[channelId] == null)
+                        channelFailoverURIs[channelId] = [];
+
+                    channelFailoverURIs[channelId].push(channelToEndpointMap[channelId]);
+                }
+            }
+            _channelSet.channelFailoverURIs = channelFailoverURIs;
+        }
+    }
+} */
+
+/**
+ *  @private
+ *  Stores a pending message to send when the ChannelSet does not have a
+ *  connected Channel to use immediately.
+ */
+/* class PendingSend
+{ */
+    //--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Constructor.
+     *
+     *  @param agent The MessageAgent sending the message.
+     *
+     *  @param msg The Message to send.
+     */
+   /*  public function PendingSend(agent:MessageAgent, message:IMessage)
+    {
+        super();
+        this.agent = agent;
+        this.message = message;
+    } */
+
+    //--------------------------------------------------------------------------
+    //
+    // Properties
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  The MessageAgent.
+     */
+   // public var agent:MessageAgent;
+
+    /**
+     *  @private
+     *  The Message to send.
+     */
+    /* public var message:IMessage;
+
+} */
+
+/**
+ *  @private
+ *  Helper class for handling and redispatching login and logout results or faults.
+ */
+/* class AuthenticationAgent extends MessageAgent
+{
+   */  //--------------------------------------------------------------------------
+    //
+    // Public Static Constants
+    //
+    //--------------------------------------------------------------------------
+
+    // State constants.
+   /*  public static const LOGGED_OUT_STATE:int = 0;
+    public static const LOGGING_IN_STATE:int = 1;
+    public static const LOGGED_IN_STATE:int = 2;
+    public static const LOGGING_OUT_STATE:int = 3;
+    public static const SHUTDOWN_STATE:int = 4; */
+
+    //--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function AuthenticationAgent(channelSet:ChannelSet)
+    {
+        _log = Log.getLogger("ChannelSet.AuthenticationAgent");
+        _agentType = "authentication agent";
+        // Must set log and agent type before assigning channelSet.
+        this.channelSet = channelSet;
+    } */
+
+    //--------------------------------------------------------------------------
+    //
+    // Variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     * Map of login/logout message Ids to associated tokens.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+   // private var tokens:Object = {};
+
+    //--------------------------------------------------------------------------
+    //
+    // Properties
+    //
+    //--------------------------------------------------------------------------
+
+  //  private var _state:int = LOGGED_OUT_STATE;
+
+    /**
+     * Returns the current state for the agent.
+     * See the static state constants defined by this class.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+   /*  public function get state():int
+    {
+        return _state;
+    }
+
+    public function set state(value:int):void
+    {
+        _state = value;
+        if (value == SHUTDOWN_STATE)
+            tokens = null;
+    } */
+
+    //--------------------------------------------------------------------------
+    //
+    // Public Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     * Registers an outbound login/logout message and its associated token for response/fault handling.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+    /* public function registerToken(token:AsyncToken):void
+    {
+        tokens[token.message.messageId] = token;
+    }
+ */
+    /**
+     * Acknowledge message callback.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+   /*  override public function acknowledge(ackMsg:AcknowledgeMessage, msg:IMessage):void
+    {
+        if (state == SHUTDOWN_STATE)
+            return;
+
+        var error:Boolean = ackMsg.headers[AcknowledgeMessage.ERROR_HINT_HEADER];
+        // Super will clean the error hint from the message.
+        super.acknowledge(ackMsg, msg);
+        // If acknowledge is *not* for a message that caused an error
+        // dispatch a result event.
+        if (!error)
+        {
+            var token:AsyncToken = tokens[msg.messageId];
+            delete tokens[msg.messageId];
+            channelSet.authenticationSuccess(this, token, ackMsg as AcknowledgeMessage);
+        }
+    } */
+
+    /**
+     * Fault callback.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
+     */
+   /*  override public function fault(errMsg:ErrorMessage, msg:IMessage):void
+    {
+        if (state == SHUTDOWN_STATE)
+            return;
+
+        // For some channel impls, when a logout request is processed the session at the remote host host
+        // is invalidated which may trigger a disconnection/drop of the channel connection.
+        // This channel disconnect may mask the logout ack. If the root cause for this error is a channel disconnect,
+        // assume logout succeeded and locally acknowledge it.
+        if (errMsg.rootCause is ChannelEvent && (errMsg.rootCause as ChannelEvent).type == ChannelEvent.DISCONNECT)
+        {
+            var ackMsg:AcknowledgeMessage = new AcknowledgeMessage();
+            ackMsg.clientId = clientId;
+            ackMsg.correlationId = msg.messageId;
+            acknowledge(ackMsg, msg);
+            return;
+        }
+
+        super.fault(errMsg, msg);
+
+        var token:AsyncToken = tokens[msg.messageId];
+        delete tokens[msg.messageId];
+        channelSet.authenticationFailure(this, token, errMsg as ErrorMessage);
+    }
+} */
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
alinakazi@apache.org.