/// <summary>
		/// Adds a new <see cref="ClientTransport"/> into this registry.
		/// </summary>
		public virtual void Add(ClientTransport transport)
		{
			if (transport != null)
			{
				string transportName = transport.Name;
				lock (_transports)
					_transports[transportName] = transport;

				lock (_allowedTransports)
				{
					if (!_allowedTransports.Contains(transportName))
						_allowedTransports.Add(transportName);
				}
			}
		}
        /// <summary>
        /// Adds a new <see cref="ClientTransport"/> into this registry.
        /// </summary>
        public virtual void Add(ClientTransport transport)
        {
            if (transport != null)
            {
                string transportName = transport.Name;
                lock (_transports)
                    _transports[transportName] = transport;

                lock (_allowedTransports)
                {
                    if (!_allowedTransports.Contains(transportName))
                    {
                        _allowedTransports.Add(transportName);
                    }
                }
            }
        }
        /// <summary>
        /// Returns a list of requested transports that exists in this registry.
        /// </summary>
        public virtual IList <ClientTransport> Negotiate(
            IEnumerable <string> requestedTransports, string bayeuxVersion)
        {
            IList <ClientTransport> list = new List <ClientTransport>();

            if (null != requestedTransports)
            {
                foreach (string transportName in requestedTransports)
                {
                    if (!String.IsNullOrEmpty(transportName) &&
                        _allowedTransports.Contains(transportName))
                    {
                        ClientTransport transport = this.GetTransport(transportName);
                        if (transport != null && transport.Accept(bayeuxVersion))
                        {
                            list.Add(transport);
                        }
                    }
                }
            }

            return(list);
        }
		/// <summary>
		/// Initializes a new instance of the <see cref="DisconnectingState"/> class
		/// for the specified <paramref name="clientId"/>.
		/// </summary>
		public DisconnectingState(BayeuxClient session, ClientTransport transport, string clientId)
			: base(session, BayeuxClientStates.Disconnecting, null, null, transport, clientId, 0) { }
		/// <summary>
		/// Initializes a new instance of the <see cref="ConnectedState"/> class
		/// with the specified handshaking message template: <paramref name="handshakeFields"/>,
		/// and the last received information from a Bayeux server like: <paramref name="advice"/>, <paramref name="clientId"/>.
		/// </summary>
		public ConnectedState(
			BayeuxClient session,
			IDictionary<string, object> handshakeFields,
			IDictionary<string, object> advice,
			ClientTransport transport,
			string clientId)
			: base(session, BayeuxClientStates.Connected, handshakeFields, advice, transport, clientId, 0)
		{
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="UnconnectedState"/> class
		/// with the specified handshaking message template: <paramref name="handshakeFields"/>,
		/// and the last received information from a Bayeux server like: <paramref name="advice"/>, <paramref name="clientId"/>.
		/// </summary>
		public UnconnectedState(
			BayeuxClient session,
			IDictionary<string, object> handshakeFields,
			IDictionary<string, object> advice,
			ClientTransport transport,
			string clientId,
			long backOff)
			: base(session, BayeuxClientStates.Unconnected, handshakeFields, advice, transport, clientId, backOff)
		{
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="ReHandshakingState"/> class
		/// with the specified handshaking message template: <paramref name="handshakeFields"/>.
		/// </summary>
		public ReHandshakingState(
			BayeuxClient session,
			IDictionary<string, object> handshakeFields,
			ClientTransport transport,
			long backOff)
			: base(session, BayeuxClientStates.ReHandshaking, handshakeFields, null, transport, null, backOff)
		{
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="HandshakingState"/> class
		/// with the specified handshaking message template: <paramref name="handshakeFields"/>.
		/// </summary>
		public HandshakingState(
			BayeuxClient session,
			IDictionary<string, object> handshakeFields,
			ClientTransport transport)
			: base(session, BayeuxClientStates.Handshaking, handshakeFields, null, transport, null, 0)
		{
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="AbortedState"/> class.
		/// </summary>
		public AbortedState(BayeuxClient session, ClientTransport transport)
			: base(session, transport) { }
		/// <summary>
		/// Initializes a new instance of the <see cref="DisconnectedState"/> class.
		/// </summary>
		public DisconnectedState(BayeuxClient session, ClientTransport transport)
			: base(session, BayeuxClientStates.Disconnected, null, null, transport, null, 0)
		{
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="BayeuxClientState"/> class
		/// with the specified <see cref="BayeuxClientStates"/> type.
		/// </summary>
		protected BayeuxClientState(
			BayeuxClient session,
			BayeuxClientStates type,
			IDictionary<string, object> handshakeFields,
			IDictionary<string, object> advice,
			ClientTransport transport,
			string clientId,
			long backOff)
		{
			if (session == null)
				throw new ArgumentNullException("session");
			if (type == BayeuxClientStates.None)
				throw new ArgumentOutOfRangeException("type");
			if (transport == null)
				throw new ArgumentNullException("transport");

			_session = session;

			_type = type;
			_handshakeFields = handshakeFields;
			_advice = advice;
			_transport = transport;
			_clientId = clientId;
			_backOff = backOff;
		}