internal void CloseInputChannel( SoapUdpInputChannel channel )
        {
            lock ( InputChannels.SyncRoot )
            {
                //
                // remove the channel
                //
                if ( InputChannels.Contains( channel ) )
                    InputChannels.Remove( channel );
                //
                // Decrement reference count on the socket for active channels
                //
                lock ( _sockets )
                {
                    IPEndPoint localEP = GetLocalIPEndPoint( channel.LocalEndpoint.TransportAddress );
                    SoapUdpSocket socket = _sockets[ localEP ] as SoapUdpSocket;

                    if ( socket != null )
                    {
                        if ( socket.ReleaseReference( ) == 0 )
                        {
                            socket.Close( );

                            _sockets.Remove( localEP );
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Build an ISoapInputChannel for the specified endpoint.
        /// </summary>
        /// <param name="endpoint"></param>
        /// <param name="capabilities"></param>
        /// <returns></returns>
        ISoapInputChannel ISoapTransport.GetInputChannel( EndpointReference endpoint, SoapChannelCapabilities capabilities )
        {
            if ( endpoint == null )
                throw new ArgumentNullException( "endpoint" );

            if ( capabilities == SoapChannelCapabilities.ActivelyListening && endpoint.TransportAddress.Scheme != UriScheme )
                throw new ArgumentException( "Invalid Transport Scheme specified" );

            if ( capabilities != SoapChannelCapabilities.None && capabilities != SoapChannelCapabilities.ActivelyListening )
                throw new NotSupportedException( "Unsupported SoapChannelCapabilities Flags" );

            Debug( "GetInputChannel TransportAddress: " + endpoint.TransportAddress.ToString( ) );
            //
            // NOTE: Transport level receiving requires that we map the transport address to
            //       one of the local interfaces for the machine.
            //
            IPEndPoint localEP = GetLocalIPEndPoint( endpoint.TransportAddress );

            if ( localEP == null )
                throw new ArgumentException( "Transport address " + endpoint.TransportAddress.ToString( ) + " could not be mapped to a local network interface." );
            //
            // Lock the InputChannels collection while we register the new channel.
            //
            lock ( InputChannels.SyncRoot )
            {
                //
                // Determine whether the request channel already exists.
                //
                SoapUdpInputChannel channel = InputChannels[ endpoint ] as SoapUdpInputChannel;
                SoapUdpSocket socket;

                if ( channel != null )
                    return channel;
                //
                // Lock the sockets collection while checking for an existing socket
                // or creating a new one.
                //
                lock ( _sockets )
                {
                    socket = _sockets[ localEP ] as SoapUdpSocket;

                    if ( socket == null )
                    {
                        //
                        // There is no suitable socket available. Create a new one,
                        // increment it's reference count and start receiving packets.
                        //
                        socket = new SoapUdpSocket( localEP, _options );
                        _sockets[ localEP ] = socket;

                        socket.AddReference( );
                        socket.BeginReceiveFrom( new AsyncCallback( OnReceiveComplete ), socket );
                    }
                    else
                    {
                        //
                        // Increment the reference count on the listener for unregister behaviour
                        //
                        socket.AddReference( );
                    }
                }
                //
                // Create the channel, then modify the via so that it matches
                // the local endpoint address.
                //
                // TODO: Fix the race condition here where a packet might be
                //       received before the channel is established for
                //       dispatching.
                //
                channel = new SoapUdpInputChannel( endpoint, socket, this );
                //
                // TODO: Do not do Via for the Any address
                //
                channel.LocalEndpoint.Via = new Via( ConvertToUri( localEP ) );
                //
                // Record the channel
                //
                InputChannels.Add( channel );

                return channel;
            }
        }