// private static methods
        private static MongoCredential FromComponents(string mechanism, string source, string username, MongoIdentityEvidence evidence)
        {
            var defaultedMechanism = (mechanism ?? "DEFAULT").Trim().ToUpperInvariant();

            switch (defaultedMechanism)
            {
            case "DEFAULT":
            case "MONGODB-CR":
            case "SCRAM-SHA-1":
            case "SCRAM-SHA-256":
                // it is allowed for a password to be an empty string, but not a username
                source = source ?? "admin";
                if (evidence == null || !(evidence is PasswordEvidence))
                {
                    var message = string.Format("A {0} credential must have a password.", defaultedMechanism);
                    throw new ArgumentException(message);
                }

                return(new MongoCredential(
                           mechanism,
                           new MongoInternalIdentity(source, username),
                           evidence));

            case "MONGODB-X509":
                // always $external for X509.
                source = "$external";
                if (evidence == null || !(evidence is ExternalEvidence))
                {
                    throw new ArgumentException("A MONGODB-X509 does not support a password.");
                }

                return(new MongoCredential(
                           mechanism,
                           new MongoX509Identity(username),
                           evidence));

            case "GSSAPI":
                // always $external for GSSAPI.
                source = "$external";

                return(new MongoCredential(
                           "GSSAPI",
                           new MongoExternalIdentity(source, username),
                           evidence));

            case "PLAIN":
                source = source ?? "admin";
                if (evidence == null || !(evidence is PasswordEvidence))
                {
                    throw new ArgumentException("A PLAIN credential must have a password.");
                }

                MongoIdentity identity;
                if (source == "$external")
                {
                    identity = new MongoExternalIdentity(source, username);
                }
                else
                {
                    identity = new MongoInternalIdentity(source, username);
                }

                return(new MongoCredential(
                           mechanism,
                           identity,
                           evidence));

            default:
                throw new NotSupportedException(string.Format("Unsupported MongoAuthenticationMechanism {0}.", mechanism));
            }
        }
        // private static methods
        private static MongoCredential FromComponents(string mechanism, string source, string username, MongoIdentityEvidence evidence)
        {
            if (string.IsNullOrEmpty(mechanism))
            {
                throw new ArgumentException("Cannot be null or empty.", "mechanism");
            }
            if (string.IsNullOrEmpty(username))
            {
                return(null);
            }

            switch (mechanism.ToUpperInvariant())
            {
            case "MONGODB-CR":
                // it is allowed for a password to be an empty string, but not a username
                source = source ?? "admin";
                if (evidence == null || !(evidence is PasswordEvidence))
                {
                    throw new ArgumentException("A MONGODB-CR credential must have a password.");
                }

                return(new MongoCredential(
                           mechanism,
                           new MongoInternalIdentity(source, username),
                           evidence));

            case "MONGODB-X509":
                // always $external for X509.
                source = "$external";
                if (evidence == null || !(evidence is ExternalEvidence))
                {
                    throw new ArgumentException("A MONGODB-X509 does not support a password.");
                }

                return(new MongoCredential(
                           mechanism,
                           new MongoExternalIdentity(username),
                           evidence));

            case "GSSAPI":
                // always $external for GSSAPI.
                source = "$external";

                return(new MongoCredential(
                           "GSSAPI",
                           new MongoExternalIdentity(source, username),
                           evidence));

            case "PLAIN":
                source = source ?? "admin";
                if (evidence == null || !(evidence is PasswordEvidence))
                {
                    throw new ArgumentException("A PLAIN credential must have a password.");
                }

                MongoIdentity identity;
                if (source == "$external")
                {
                    identity = new MongoExternalIdentity(source, username);
                }
                else
                {
                    identity = new MongoInternalIdentity(source, username);
                }

                return(new MongoCredential(
                           mechanism,
                           identity,
                           evidence));

            default:
                throw new NotSupportedException(string.Format("Unsupported MongoAuthenticationMechanism {0}.", mechanism));
            }
        }