public static ImapCommandResult CreateSession(IImapSessionProfile profile,
                                                  SaslClientMechanism authMechanismSpecified,
                                                  UpgradeConnectionStreamCallback createSslStreamCallback,
                                                  out ImapSession session)
        {
            if (profile == null)
            throw new ArgumentNullException("profile");

              var authority = profile.Authority;
              var securePort = string.Equals(authority.Scheme, ImapUri.UriSchemeImaps, StringComparison.OrdinalIgnoreCase);

              if (securePort && createSslStreamCallback == null)
            throw new ArgumentNullException("createSslStreamCallback");

              ImapCommandResult result;
              session = null;

              session = new ImapSession(authority.Host,
                                authority.Port,
                                true,
                                profile.Timeout,
                                securePort
                                  ? createSslStreamCallback
                                  : null);

              session.HandlesIncapableAsException = false;
              session.HandlesReferralAsException = false;
              session.TransactionTimeout  = profile.Timeout;
              session.SendTimeout         = profile.SendTimeout;
              session.ReceiveTimeout      = profile.ReceiveTimeout;

              if (session.ServerCapabilities.Count == 0)
            // try querying server capability (ignore error)
            session.Capability();

              if (!session.ServerCapabilities.Has(ImapCapability.Imap4Rev1))
            throw new ImapIncapableException(ImapCapability.Imap4Rev1);

              if (profile.UseTlsIfAvailable && session.ServerCapabilities.Has(ImapCapability.StartTls) && !session.IsSecureConnection) {
            var r = session.StartTls(createSslStreamCallback, true);

            if (r.Failed)
              throw new ImapSecureConnectionException(r.ResultText);
            else if (!session.ServerCapabilities.Has(ImapCapability.Imap4Rev1))
              throw new ImapIncapableException(ImapCapability.Imap4Rev1);
              }

              if (profile.UseDeflateIfAvailable && session.ServerCapabilities.Has(ImapCapability.CompressDeflate)) {
            var r = session.Compress(ImapCompressionMechanism.Deflate);

            if (r.Failed)
              throw new WebException(r.ResultText, null, WebExceptionStatus.RequestCanceled, null);
              }

              if (authMechanismSpecified == null)
            result = Authenticate(session, profile);
              else
            result = session.Authenticate(authMechanismSpecified);

              if (result == null) {
            throw new ImapAuthenticationException("appropriate authentication mechanism not found");
              }
              else if (result.Failed) {
            try {
              try {
            session.Disconnect(false);
              }
              catch (ImapConnectionException) {
            // ignore
              }
            }
            finally {
              session = null;
            }
              }

              return result;
        }