/// <summary>
        /// Start to listen on a named pipe.
        /// </summary>
        /// <param name="namedPipe">The name of named pipe to listen on.</param>
        /// <param name="credential">Credential to be used by underlayer SMB/SMB2 transport.</param>
        /// <exception cref="InvalidOperationException">
        /// Thrown when the server with the named pipe has been started.
        /// </exception>
        /// <param name="ipAddress">server's ipAddress</param>
        public virtual RpceServerContext StartNamedPipe(string namedPipe, AccountCredential credential, 
            IPAddress ipAddress)
        {
            namedPipe = namedPipe.ToUpper();

            lock (this.smbThreadLocker)
            {
                RpceServerContext serverContext = this.serverContextManager.LookupServerContext(
                    RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE,
                    namedPipe);

                if (serverContext != null)
                {
                    throw new InvalidOperationException("The server with the named pipe has been started. Please try other port.");
                }

                serverContext = new RpceServerContext(
                        RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE,
                        namedPipe,
                        credential);

                this.serverContextManager.AddServerContext(serverContext);
                if (this.openedNamedPipeList == null)
                {
                    this.openedNamedPipeList = new List<string>();
                }
                this.openedNamedPipeList.Add(namedPipe);

                try
                {
                    if (this.smbTransport == null)
                    {
                        this.smbTransport = new Smb.SmbServerTransport();
                        this.smbTransport.Start(RpceUtility.NAMED_PIPE_PORT, credential, ipAddress);
                    }
                }
                catch
                {
                    this.serverContextManager.RemoveServerContext(serverContext);
                    this.openedNamedPipeList.Remove(namedPipe);
                    throw;
                }

                if (this.smbReceiveThread == null)
                {
                    this.smbReceiveThread = new Thread(SmbReceiveLoop);
                    this.smbReceiveThread.Start();
                }

                return serverContext;
            }
        }
        /// <summary>
        /// Dispose method.
        /// </summary>
        /// <param name="disposing">
        /// True to release both managed and unmanaged resources.<para/>
        /// False to release unmanaged resources only.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                Thread tcpThread = this.tcpReceiveThread;
                Thread smbThread = this.smbReceiveThread;

                this.StopAll();

                if (tcpThread != null)
                {
                    tcpThread.Join();
                }

                if (smbThread != null)
                {
                    smbThread.Join();
                }

                if (disposing)
                {
                    //Release managed resources.
                    if (this.tcpTransport != null)
                    {
                        this.tcpTransport.Dispose();
                        this.tcpTransport = null;
                    }

                    if (this.smbTransport != null)
                    {
                        this.smbTransport.Dispose();
                        this.smbTransport = null;
                    }

                    this.receivedTransportEvents.Dispose();
                }

                this.disposed = true;
            }
        }