/// <summary>
        /// Adds a specified client sink provider into the client sink chain after the formatter.
        /// </summary>
        /// <param name="protocolSetup">Protocol setup</param>
        /// <param name="clientSinkProvider">Client sink provider to be added</param>
        /// <returns>Protocol setup</returns>
        public static IServerProtocolSetup AddClientSinkAfterFormatter(this IServerProtocolSetup protocolSetup, IClientChannelSinkProvider clientSinkProvider)
        {
            if (protocolSetup == null)
            {
                throw new ArgumentNullException("protocolSetup");
            }

            if (clientSinkProvider == null)
            {
                throw new ArgumentNullException("clientSinkProvider");
            }

            IClientFormatterSinkProvider formatter = GetClientFormatter(protocolSetup);

            if (formatter == null)
            {
                throw new ApplicationException(LanguageResource.ApplicationException_NoFormatterSpecified);
            }

            int index = protocolSetup.ClientSinkChain.IndexOf((IClientChannelSinkProvider)formatter);

            protocolSetup.ClientSinkChain.Insert(index + 1, clientSinkProvider);

            return(protocolSetup);
        }
        /// <summary>
        /// Erzeugt einen fertig konfigurierten Remoting-Kanal.
        /// <remarks>
        /// Wenn der Kanal in der aktuellen Anwendungsdomäne bereits registriert wurde, wird null zurückgegeben.
        /// </remarks>
        /// </summary>
        /// <returns>Remoting Kanal</returns>
        public IChannel CreateChannel()
        {
            // Kanal suchen
            IChannel channel = ChannelServices.GetChannel(_channelName);

            // Wenn der Kanal nicht gefunden wurde ...
            if (channel == null)
            {
                // Konfiguration für den HTTP-Kanal erstellen
                System.Collections.IDictionary channelSettings = new System.Collections.Hashtable();
                channelSettings["name"] = _channelName;
                channelSettings["port"] = 0;

                // Variable für Clientformatierer
                IClientFormatterSinkProvider clientFormatter = null;

                // Wenn binäre Formatierung verwendet werden soll ...
                if (_useBinaryFormatter)
                {
                    // Binären Clientformatierer erzeugen
                    clientFormatter = new BinaryClientFormatterSinkProvider();
                }
                else
                {
                    // SOAP Clientformatierer erzeugen
                    clientFormatter = new SoapClientFormatterSinkProvider();
                }

                // Wenn die Kommunikation verschlüsselt werden soll ...
                if (_encryption)
                {
                    // Client-Verschlüsselungs-Kanalsenkenanbieter erzeugen
                    CryptoClientChannelSinkProvider clientEncryption = new CryptoClientChannelSinkProvider();

                    // Verschlüsselung konfigurieren
                    clientEncryption.Algorithm   = _algorithm;
                    clientEncryption.Oaep        = _oaep;
                    clientEncryption.MaxAttempts = _maxAttempts;

                    // Verschlüsselungs-Kanalsenkenanbieter hinter den Formatierer hängen
                    clientFormatter.Next = clientEncryption;
                }
                // Variable für ersten Server-Senkenanbieter in der Kette
                IServerChannelSinkProvider firstServerSinkProvider = null;

                // Variable für Serverformatierer
                IServerFormatterSinkProvider serverFormatter = null;

                // Wenn binäre Formatierung verwendet werden soll ...
                if (_useBinaryFormatter)
                {
                    // Binären Serverformatierer erzeugen
                    serverFormatter = new BinaryServerFormatterSinkProvider();

                    // Serialisierung von komplexen Objekten aktivieren
                    ((BinaryServerFormatterSinkProvider)serverFormatter).TypeFilterLevel = TypeFilterLevel.Full;
                }
                else
                {
                    // SOAP Serverformatierer erzeugen
                    serverFormatter = new SoapServerFormatterSinkProvider();

                    // Serialisierung von komplexen Objekten aktivieren
                    ((SoapServerFormatterSinkProvider)serverFormatter).TypeFilterLevel = TypeFilterLevel.Full;
                }
                // Wenn die Kommunikation verschlüsselt werden soll ...
                if (_encryption)
                {
                    // Server-Verschlüsselungs-Kanalsenkenanbieter erzeugen
                    CryptoServerChannelSinkProvider serverEncryption = new CryptoServerChannelSinkProvider();

                    // Verschlüsselung konfigurieren
                    serverEncryption.Algorithm           = _algorithm;
                    serverEncryption.Oaep                = _oaep;
                    serverEncryption.RequireCryptoClient = true;

                    // Formatierer hinter den Verschlüsselungs-Kanalsenkenanbieter hängen
                    serverEncryption.Next = serverFormatter;

                    // Verschlüsselungs-Kanalsenkenanbieter als ersten Senkenanbieter festlegen
                    firstServerSinkProvider = serverEncryption;
                }
                else
                {
                    // Server-Formatierer als ersten Senkenanbieter festlegen
                    firstServerSinkProvider = serverFormatter;
                }

                // Neuen HTTP-Kanal erzeugen
                channel = new HttpChannel(channelSettings, clientFormatter, firstServerSinkProvider);

                // Wenn Zyan nicht mit mono ausgeführt wird ...
                if (!MonoCheck.IsRunningOnMono)
                {
                    // Sicherstellen, dass vollständige Ausnahmeinformationen übertragen werden
                    if (RemotingConfiguration.CustomErrorsMode != CustomErrorsModes.Off)
                    {
                        RemotingConfiguration.CustomErrorsMode = CustomErrorsModes.Off;
                    }
                }
                // Kanal zurückgeben
                return(channel);
            }
            // Nichts zurückgeben
            return(null);
        }