protected HandshakeSession(SecurityParameters securityParameters, ILogger logger)
        {
            this.logger = logger;

            _pluginManager = new CipherSuitePluginManager(this.logger);
            _state = HandshakeState.Initial;

            _minVersion = securityParameters.MinimumVersion;
            _maxVersion = securityParameters.MaximumVersion;
            _supportedCipherSuites = securityParameters.CipherSuiteIDs.ToArray();
            _supportedCompressions = securityParameters.CompressionIDs.ToArray();

            _availableCertificates = new List<X509CertificateCollection>(securityParameters.AvailableCertificates);
            _availablePrivateKeys = new List<CertificatePrivateKey>(securityParameters.AvailablePrivateKeys);

            _clientCertificates = new X509CertificateCollection();
            _serverCertificates = new X509CertificateCollection();

            // Initialize the default ClientHello version, to
            // be as compatible as possible based on maxVersion
            _version = _minVersion;

            
            _cipherSuite = new CipherSuite(_version);
        }
        private static CipherSuite SelectCipherSuite(CipherSuitePluginManager pluginManager,
            ProtocolVersion clientVersion, ProtocolVersion minVersion, ProtocolVersion maxVersion,
            List<CipherSuiteId> clientSuites, List<CipherSuiteId> serverSuites,
            ServerCertificateSelectionCallback certificateSelectionCallback,
            List<X509CertificateCollection> availableCertificates)
        {
            if (clientVersion < minVersion)
            {
                throw new AlertException(AlertDescription.ProtocolVersion,
                                         "Offered client version " + clientVersion +
                                         " lower than minimum supported version " + minVersion);
            }

            // Initialize our return value as null
            CipherSuite selectedCipherSuite = null;

            // Run as long as we either select a cipher suite or run out of versions
            ProtocolVersion selectedVersion = clientVersion < maxVersion ? clientVersion : maxVersion;
            while (selectedCipherSuite == null)
            {
                foreach (CipherSuiteId id in clientSuites)
                {
                    if (!serverSuites.Contains(id))
                        continue;

                    // Try initializing the cipher suite based on ID
                    selectedCipherSuite = pluginManager.GetCipherSuite(selectedVersion, (ushort)id);
                    if (selectedCipherSuite == null)
                        continue;

                    // Try selecting a suitable certificate for this cipher suite
                    int certificateIndex = certificateSelectionCallback(selectedCipherSuite, availableCertificates.ToArray());
                    if (certificateIndex >= 0 && certificateIndex < availableCertificates.Count)
                    {
                        // We finally found the valid suite, break out from the loop
                        break;
                    }
                    // No certificate was found for the suite, ignore
                    selectedCipherSuite = null;
                }

                if (selectedCipherSuite != null) break;
                if (selectedVersion == minVersion) break;
                selectedVersion = selectedVersion.PreviousProtocolVersion;
            }

            if (selectedCipherSuite == null)
            {
                throw new AlertException(AlertDescription.HandshakeFailure,
                                         "None of the cipher suites offered by client is accepted");
            }
            return selectedCipherSuite;
        }