             guard clientSettings.hosts.count == 1 else {
                 throw MongoError.noServersAvailable
             }
-            
-            clientSettings.hosts[0].isPrimary = true
-            clientSettings.hosts[0].online = true
-            
-            let connection = try makeConnection(toHost: clientSettings.hosts[0], authenticatedFor: nil)
+
+            self.clientSettings.hosts[0].isPrimary = true
+            self.clientSettings.hosts[0].online = true
+
+            let connection = try makeConnection(toHost: self.clientSettings.hosts[0], authenticatedFor: nil)
             connection.used = true
-            
+
             defer {
                 returnConnection(connection)
             }
-            
+
             connections.append(connection)
-            
-            let authDB = self[authentication?.database ?? "admin"]
+
+            let authDB = self[self.clientSettings.credentials?.database ?? "admin"]
             let cmd = authDB["$cmd"]
             let document: Document = [
                 "isMaster": Int32(1)
             ]
-            
+
             let commandMessage = Message.Query(requestID: self.nextMessageID(), flags: [], collection: cmd, numbersToSkip: 0, numbersToReturn: 1, query: document, returnFields: nil)
             let response = try self.sendAndAwait(message: commandMessage, overConnection: connection, timeout: defaultTimeout)
-            
+
             guard case .Reply(_, _, _, _, _, _, let documents) = response, let doc = documents.first else {
                 throw InternalMongoError.incorrectReply(reply: response)
             }
-            
+
             guard let batchSize = doc["maxWriteBatchSize"] as Int32?, let minWireVersion = doc["minWireVersion"] as Int32?, let maxWireVersion = doc["maxWireVersion"] as Int32? else {
                 serverData = (maxWriteBatchSize: 1000, maxWireVersion: 4, minWireVersion: 0, maxMessageSizeBytes: 48000000)
                 return
             }
-            
+
             var maxMessageSizeBytes = doc["maxMessageSizeBytes"] as Int32? ?? 0
             if maxMessageSizeBytes == 0 {
                 maxMessageSizeBytes = 48000000
             }
-            
+
             self.serverData = (maxWriteBatchSize: batchSize, maxWireVersion: maxWireVersion, minWireVersion: minWireVersion, maxMessageSizeBytes: maxMessageSizeBytes)
         }
-        
+
         self.connectionPoolMaintainanceQueue.async(execute: backgroundLoop)
+
+    }
+
+    /// Sets up the `Server` to connect to the specified URL.
+    /// The `mongodb://` scheme is required as well as the host. Optionally youc an provide ausername + password. And if no port is specified `27017` is used.
+    /// You can provide an alternative TCP Driver that complies to `MongoTCP`.
+    /// This Server doesn't connect automatically. You need to either use the `connect` function yourself or specify the `automatically` parameter to be true.
+    ///
+    /// - parameter url: The MongoDB connection String.
+    /// - parameter tcpDriver: The TCP Driver to be used to connect to the server. Recommended to change to an SSL supporting socket when connnecting over the public internet.
+    ///
+    /// - throws: When we can't connect automatically, when the scheme/host is invalid and when we can't connect automatically
+    ///
+    /// - parameter automatically: Whether to connect automatically
+    convenience public init(mongoURL url: String, maxConnectionsPerServer maxConnections: Int = 10, defaultTimeout: TimeInterval = 30) throws {
+        let clientSettings = try ClientSettings(mongoURL: url)
+        try self.init(clientSettings)
+    }
+
+    /// Sets up the `Server` to connect to the specified location.`Server`
+    /// You need to provide a host as IP address or as a hostname recognized by the client's DNS.
+    /// - parameter at: The hostname/IP address of the MongoDB server
+    /// - parameter port: The port we'll connect on. Defaults to 27017
+    /// - parameter authentication: The optional authentication details we'll use when connecting to the server
+    /// - parameter automatically: Connect automatically
+    ///
+    /// - throws: When we can’t connect automatically, when the scheme/host is invalid and when we can’t connect automatically
+    convenience public init(hostname host: String, port: UInt16 = 27017, authenticatedAs authentication: MongoCredentials? = nil, maxConnectionsPerServer maxConnections: Int = 10, ssl sslSettings: SSLSettings? = nil) throws {
+        let clientSettings = ClientSettings(host: MongoHost(hostname:host, port:port), sslSettings: sslSettings, credentials: authentication, maxConnectionsPerServer: maxConnections)
+        try self.init(clientSettings)
     }
     
     var maintainanceLoopCalls = [(()->())]()

        
        reinitializeReplica = false
    }


    public init(_ clientSettings: ClientSettings) throws {
        self.clientSettings = clientSettings
        
        if let sslSettings = clientSettings.sslSettings {
            self.tcpType = sslSettings.enabled ? DefaultSSLTCPClient : DefaultTCPClient
            self.sslVerify = !sslSettings.invalidCertificateAllowed
        } else {
            self.tcpType = DefaultTCPClient
        }

        self.maximumConnections = clientSettings.maxConnectionsPerServer
        self.defaultTimeout = clientSettings.defaultTimeout
        self.maximumConnectionsPerHost = clientSettings.maxConnectionsPerServer
        self.connectionPoolSemaphore = DispatchSemaphore(value: clientSettings.maxConnectionsPerServer)

        self.servers = servers.map({ (host) -> MongoHost in
            var host = host
            host.isPrimary = true
            host.online = true
            host.openConnections = 0
            return host
        })

        let authDB = self[clientSettings.credentials?.database ?? "admin"]

        let doc = try authDB.isMaster()

        guard let batchSize = doc["maxWriteBatchSize"] as Int32?, let minWireVersion = doc["minWireVersion"] as Int32?, let maxWireVersion = doc["maxWireVersion"] as Int32? else {
            debug("No usable ismaster response found. Assuming defaults.")
            serverData = (maxWriteBatchSize: 1000, maxWireVersion: 4, minWireVersion: 0, maxMessageSizeBytes: 48000000)
            return
        }

        var maxMessageSizeBytes = doc["maxMessageSizeBytes"] as Int32? ?? 0
        if maxMessageSizeBytes == 0 {
            maxMessageSizeBytes = 48000000
        }

        serverData = (maxWriteBatchSize: batchSize, maxWireVersion: maxWireVersion, minWireVersion: minWireVersion, maxMessageSizeBytes: maxMessageSizeBytes)

        self.connectionPoolMaintainanceQueue.async(execute: backgroundLoop)
    }

    /// Sets up the `Server` to connect to the specified location.`Server`
    /// You need to provide a host as IP address or as a hostname recognized by the client's DNS.
    /// - parameter at: The hostname/IP address of the MongoDB server
    /// - parameter port: The port we'll connect on. Defaults to 27017
    /// - parameter authentication: The optional authentication details we'll use when connecting to the server
    /// - parameter automatically: Connect automatically
    ///
    /// - throws: When we can’t connect automatically, when the scheme/host is invalid and when we can’t connect automatically
    public init(hostname host: String, port: UInt16 = 27017, authenticatedAs authentication: MongoCredentials? = nil, maxConnectionsPerServer maxConnections: Int = 10, ssl sslSettings: SSLSettings? = nil) throws {
        var host = MongoHost(hostname: host, port: port)
        host.isPrimary = true
        host.online = true
        host.openConnections = 0
        
        self.clientSettings = ClientSettings(hosts: [host], sslSettings: sslSettings, credentials: authentication)
        self.clientSettings.maxConnectionsPerServer = maxConnections
        
        self.tcpType = sslSettings?.enabled == true ? DefaultSSLTCPClient : DefaultTCPClient
        self.connectionPoolSemaphore = DispatchSemaphore(value: maxConnections)
        
        logger.registerFramework(self)
        _ = try? logger.registerSubject(Document.self, forFramework: self)
        
        let authDB = self[authentication?.database ?? "admin"]
        
        let doc = try authDB.isMaster()
        
        guard let batchSize = doc["maxWriteBatchSize"] as Int32?, let minWireVersion = doc["minWireVersion"] as Int32?, let maxWireVersion = doc["maxWireVersion"] as Int32? else {
            debug("No usable ismaster response found. Assuming defaults.")
            serverData = (maxWriteBatchSize: 1000, maxWireVersion: 4, minWireVersion: 0, maxMessageSizeBytes: 48000000)
            return
        }
        
        var maxMessageSizeBytes = doc["maxMessageSizeBytes"] as Int32? ?? 0
        if maxMessageSizeBytes == 0 {
            maxMessageSizeBytes = 48000000
        }
        
        serverData = (maxWriteBatchSize: batchSize, maxWireVersion: maxWireVersion, minWireVersion: minWireVersion, maxMessageSizeBytes: maxMessageSizeBytes)
        
        self.connectionPoolMaintainanceQueue.async(execute: backgroundLoop)
    }
    
    private func makeConnection(writing: Bool = true, authenticatedFor: Database?) throws -> Connection {
        verbose("Attempting to create a new connection")


    internal private(set) var serverData: (maxWriteBatchSize: Int32, maxWireVersion: Int32, minWireVersion: Int32, maxMessageSizeBytes: Int32)?
    
    /// Sets up the `Server` to connect to MongoDB.
    ///
    /// - Parameter clientSettings: The Client Settings
    /// - Throws: When we can't connect automatically, when the scheme/host is invalid and when we can't connect automatically
    public init(_ clientSettings: ClientSettings) throws {
        self.clientSettings = clientSettings

        if let sslSettings = clientSettings.sslSettings {
            self.tcpType = sslSettings.enabled ? DefaultSSLTCPClient : DefaultTCPClient
            self.sslVerify = !sslSettings.invalidCertificateAllowed
        } else {
            self.tcpType = DefaultTCPClient
        }

        self.connectionPoolSemaphore = DispatchSemaphore(value: self.clientSettings.maxConnectionsPerServer * self.clientSettings.hosts.count)
        self.defaultTimeout = self.clientSettings.defaultTimeout
        self.logger = Logger.default
        logger.registerFramework(self)
        _ = try? logger.registerSubject(Document.self, forFramework: self)

        if clientSettings.hosts.count > 1 {
            self.isReplica = true
            initializeReplica()
