Made it so that we can inject more tha one TLS protocol version
diff --git a/checkstyle.xml b/checkstyle.xml
index 864649b..d695476 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -25,6 +25,10 @@
   <property name="localeLanguage" value="en"/>
   <module name="JavadocPackage"/>
 
+  <module name="ArrayTypeStyle">
+    <property name="javaStyle" value="true"/>
+  </module>
+
   <module name="LineLength">
     <property name="fileExtensions" value="java"/>
     <property name="max" value="120"/>
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/AUTH.java b/core/src/main/java/org/apache/ftpserver/command/impl/AUTH.java
index b5956cd..3e7fa1a 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/AUTH.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/AUTH.java
@@ -139,8 +139,8 @@
             sslFilter.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
             }
     
-            if (ssl.getEnabledProtocol() != null) {
-            sslFilter.setEnabledProtocols(new String[] { ssl.getEnabledProtocol() });
+            if (ssl.getEnabledProtocols() != null) {
+                sslFilter.setEnabledProtocols(ssl.getEnabledProtocols());
             }
     
             session.getFilterChain().addFirst(SSL_SESSION_FILTER_NAME, sslFilter);
diff --git a/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java b/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
index 9c668b3..428ddc2 100644
--- a/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
+++ b/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
@@ -215,6 +215,7 @@
             }
 
             String protocol = SpringUtil.parseString(sslElm, "protocol");
+            
             if (protocol != null) {
                 ssl.setSslProtocol(protocol);
             }
diff --git a/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java b/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java
index bf1b792..180800f 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java
@@ -72,11 +72,11 @@
     FtpIoSession session;
 
     public IODataConnectionFactory(final FtpServerContext serverContext, final FtpIoSession session) {
-    this.session = session;
-    this.serverContext = serverContext;
-    if ((session != null) && (session.getListener() != null) && session.getListener().getDataConnectionConfiguration().isImplicitSsl()) {
-        secure = true;
-    }
+        this.session = session;
+        this.serverContext = serverContext;
+        if ((session != null) && (session.getListener() != null) && session.getListener().getDataConnectionConfiguration().isImplicitSsl()) {
+            secure = true;
+        }
     }
 
     /**
@@ -120,87 +120,88 @@
      * Port command.
      */
     public synchronized void initActiveDataConnection(final InetSocketAddress address) {
-
-    // close old sockets if any
-    closeDataConnection();
-
-    // set variables
-    passive = false;
-    this.address = address.getAddress();
-    port = address.getPort();
-    requestTime = System.currentTimeMillis();
-    }
-
-    private SslConfiguration getSslConfiguration() {
-    DataConnectionConfiguration dataCfg = session.getListener().getDataConnectionConfiguration();
-
-    SslConfiguration configuration = dataCfg.getSslConfiguration();
-
-    // fall back if no configuration has been provided on the data connection config
-    if (configuration == null) {
-        configuration = session.getListener().getSslConfiguration();
-    }
-
-    return configuration;
+        // close old sockets if any
+        closeDataConnection();
+    
+        // set variables
+        passive = false;
+        this.address = address.getAddress();
+        port = address.getPort();
+        requestTime = System.currentTimeMillis();
+        }
+    
+        private SslConfiguration getSslConfiguration() {
+        DataConnectionConfiguration dataCfg = session.getListener().getDataConnectionConfiguration();
+    
+        SslConfiguration configuration = dataCfg.getSslConfiguration();
+    
+        // fall back if no configuration has been provided on the data connection config
+        if (configuration == null) {
+            configuration = session.getListener().getSslConfiguration();
+        }
+    
+        return configuration;
     }
 
     /**
      * Initiate a data connection in passive mode (server listening).
      */
     public synchronized InetSocketAddress initPassiveDataConnection() throws DataConnectionException {
-    LOG.debug("Initiating passive data connection");
-    // close old sockets if any
-    closeDataConnection();
-
-    // get the passive port
-    int passivePort = session.getListener().getDataConnectionConfiguration().requestPassivePort();
-    if (passivePort == -1) {
-        servSoc = null;
-        throw new DataConnectionException("Cannot find an available passive port.");
-    }
-
-    // open passive server socket and get parameters
-    try {
-        DataConnectionConfiguration dataCfg = session.getListener().getDataConnectionConfiguration();
-
-        String passiveAddress = dataCfg.getPassiveAddress();
-
-        if (passiveAddress == null) {
-        address = serverControlAddress;
-        } else {
-        address = resolveAddress(dataCfg.getPassiveAddress());
-        }
-
-        if (secure) {
-        LOG.debug("Opening SSL passive data connection on address \"{}\" and port {}", address, passivePort);
-        SslConfiguration ssl = getSslConfiguration();
-        if (ssl == null) {
-            throw new DataConnectionException("Data connection SSL required but not configured.");
-        }
-
-        // this method does not actually create the SSL socket, due to a JVM bug
-        // (https://issues.apache.org/jira/browse/FTPSERVER-241).
-        // Instead, it creates a regular
-        // ServerSocket that will be wrapped as a SSL socket in createDataSocket()
-        servSoc = new ServerSocket(passivePort, 0, address);
-        LOG.debug("SSL Passive data connection created on address \"{}\" and port {}", address, passivePort);
-        } else {
-        LOG.debug("Opening passive data connection on address \"{}\" and port {}", address, passivePort);
-        servSoc = new ServerSocket(passivePort, 0, address);
-        LOG.debug("Passive data connection created on address \"{}\" and port {}", address, passivePort);
-        }
-        port = servSoc.getLocalPort();
-        servSoc.setSoTimeout(dataCfg.getIdleTime() * 1000);
-
-        // set different state variables
-        passive = true;
-        requestTime = System.currentTimeMillis();
-
-        return new InetSocketAddress(address, port);
-    } catch (Exception ex) {
+        LOG.debug("Initiating passive data connection");
+        // close old sockets if any
         closeDataConnection();
-        throw new DataConnectionException("Failed to initate passive data connection: " + ex.getMessage(), ex);
-    }
+    
+        // get the passive port
+        int passivePort = session.getListener().getDataConnectionConfiguration().requestPassivePort();
+        if (passivePort == -1) {
+            servSoc = null;
+            throw new DataConnectionException("Cannot find an available passive port.");
+        }
+    
+        // open passive server socket and get parameters
+        try {
+            DataConnectionConfiguration dataCfg = session.getListener().getDataConnectionConfiguration();
+    
+            String passiveAddress = dataCfg.getPassiveAddress();
+    
+            if (passiveAddress == null) {
+                address = serverControlAddress;
+            } else {
+                address = resolveAddress(dataCfg.getPassiveAddress());
+            }
+    
+            if (secure) {
+                LOG.debug("Opening SSL passive data connection on address \"{}\" and port {}", address, passivePort);
+                SslConfiguration ssl = getSslConfiguration();
+                
+                if (ssl == null) {
+                    throw new DataConnectionException("Data connection SSL required but not configured.");
+                }
+        
+                // this method does not actually create the SSL socket, due to a JVM bug
+                // (https://issues.apache.org/jira/browse/FTPSERVER-241).
+                // Instead, it creates a regular
+                // ServerSocket that will be wrapped as a SSL socket in createDataSocket()
+                servSoc = new ServerSocket(passivePort, 0, address);
+                LOG.debug("SSL Passive data connection created on address \"{}\" and port {}", address, passivePort);
+            } else {
+                LOG.debug("Opening passive data connection on address \"{}\" and port {}", address, passivePort);
+                servSoc = new ServerSocket(passivePort, 0, address);
+                LOG.debug("Passive data connection created on address \"{}\" and port {}", address, passivePort);
+            }
+            
+            port = servSoc.getLocalPort();
+            servSoc.setSoTimeout(dataCfg.getIdleTime() * 1000);
+    
+            // set different state variables
+            passive = true;
+            requestTime = System.currentTimeMillis();
+    
+            return new InetSocketAddress(address, port);
+        } catch (Exception ex) {
+            closeDataConnection();
+            throw new DataConnectionException("Failed to initate passive data connection: " + ex.getMessage(), ex);
+        }
     }
 
     /*
@@ -209,7 +210,7 @@
      * @see org.apache.ftpserver.FtpDataConnectionFactory2#getInetAddress()
      */
     public InetAddress getInetAddress() {
-    return address;
+        return address;
     }
 
     /*
@@ -218,7 +219,7 @@
      * @see org.apache.ftpserver.FtpDataConnectionFactory2#getPort()
      */
     public int getPort() {
-    return port;
+        return port;
     }
 
     /*
@@ -227,154 +228,155 @@
      * @see org.apache.ftpserver.FtpDataConnectionFactory2#openConnection()
      */
     public DataConnection openConnection() throws Exception {
-    return new IODataConnection(createDataSocket(), session, this);
+        return new IODataConnection(createDataSocket(), session, this);
     }
 
     /**
      * Get the data socket. In case of error returns null.
      */
     private synchronized Socket createDataSocket() throws Exception {
-
-    // get socket depending on the selection
-    dataSoc = null;
-    DataConnectionConfiguration dataConfig = session.getListener().getDataConnectionConfiguration();
-    try {
-        if (!passive) {
-        if (secure) {
-            LOG.debug("Opening secure active data connection");
-            SslConfiguration ssl = getSslConfiguration();
-            if (ssl == null) {
-            throw new FtpException("Data connection SSL not configured");
+        // get socket depending on the selection
+        dataSoc = null;
+        DataConnectionConfiguration dataConfig = session.getListener().getDataConnectionConfiguration();
+        try {
+            if (!passive) {
+                if (secure) {
+                    LOG.debug("Opening secure active data connection");
+                    SslConfiguration ssl = getSslConfiguration();
+                    
+                    if (ssl == null) {
+                        throw new FtpException("Data connection SSL not configured");
+                    }
+        
+                    // get socket factory
+                    SSLSocketFactory socFactory = ssl.getSocketFactory();
+        
+                    // create socket
+                    SSLSocket ssoc = (SSLSocket) socFactory.createSocket();
+                    ssoc.setUseClientMode(false);
+        
+                    // initialize socket
+                    if (ssl.getEnabledCipherSuites() != null) {
+                        ssoc.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
+                    }
+        
+                    if (ssl.getEnabledProtocols() != null) {
+                        ssoc.setEnabledProtocols(ssl.getEnabledProtocols());
+                    }
+                    
+                    dataSoc = ssoc;
+                } else {
+                    LOG.debug("Opening active data connection");
+                    dataSoc = new Socket();
+                }
+        
+                dataSoc.setReuseAddress(true);
+        
+                InetAddress localAddr = resolveAddress(dataConfig.getActiveLocalAddress());
+        
+                // if no local address has been configured, make sure we use the same as the client connects from
+                if (localAddr == null) {
+                    localAddr = ((InetSocketAddress) session.getLocalAddress()).getAddress();
+                }
+        
+                SocketAddress localSocketAddress = new InetSocketAddress(localAddr, dataConfig.getActiveLocalPort());
+        
+                LOG.debug("Binding active data connection to {}", localSocketAddress);
+                dataSoc.bind(localSocketAddress);
+        
+                dataSoc.connect(new InetSocketAddress(address, port));
+            } else {
+    
+            if (secure) {
+                LOG.debug("Opening secure passive data connection");
+                // this is where we wrap the unsecured socket as a SSLSocket. This is
+                // due to the JVM bug described in FTPSERVER-241.
+    
+                // get server socket factory
+                SslConfiguration ssl = getSslConfiguration();
+    
+                // we've already checked this, but let's do it again
+                if (ssl == null) {
+                throw new FtpException("Data connection SSL not configured");
+                }
+    
+                SSLSocketFactory ssocketFactory = ssl.getSocketFactory();
+    
+                Socket serverSocket = servSoc.accept();
+    
+                SSLSocket sslSocket = (SSLSocket) ssocketFactory.createSocket(serverSocket, serverSocket.getInetAddress().getHostAddress(), serverSocket.getPort(), true);
+                sslSocket.setUseClientMode(false);
+    
+                // initialize server socket
+                if (ssl.getClientAuth() == ClientAuth.NEED) {
+                    sslSocket.setNeedClientAuth(true);
+                } else if (ssl.getClientAuth() == ClientAuth.WANT) {
+                    sslSocket.setWantClientAuth(true);
+                }
+    
+                if (ssl.getEnabledCipherSuites() != null) {
+                    sslSocket.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
+                }
+    
+                if (ssl.getEnabledProtocols() != null) {
+                    sslSocket.setEnabledProtocols(ssl.getEnabledProtocols());
+                }
+    
+                dataSoc = sslSocket;
+            } else {
+                LOG.debug("Opening passive data connection");
+    
+                dataSoc = servSoc.accept();
             }
-
-            // get socket factory
-            SSLSocketFactory socFactory = ssl.getSocketFactory();
-
-            // create socket
-            SSLSocket ssoc = (SSLSocket) socFactory.createSocket();
-            ssoc.setUseClientMode(false);
-
-            // initialize socket
-            if (ssl.getEnabledCipherSuites() != null) {
-            ssoc.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
+    
+            if (dataConfig.isPassiveIpCheck()) {
+                // Let's make sure we got the connection from the same
+                // client that we are expecting
+                InetAddress remoteAddress = ((InetSocketAddress) session.getRemoteAddress()).getAddress();
+                InetAddress dataSocketAddress = dataSoc.getInetAddress();
+                if (!dataSocketAddress.equals(remoteAddress)) {
+                LOG.warn("Passive IP Check failed. Closing data connection from " + dataSocketAddress + " as it does not match the expected address " + remoteAddress);
+                closeDataConnection();
+                return null;
+                }
             }
-
-            if (ssl.getEnabledProtocol() != null) {
-            ssoc.setEnabledProtocols(new String[] { ssl.getEnabledProtocol() });
+    
+            DataConnectionConfiguration dataCfg = session.getListener().getDataConnectionConfiguration();
+    
+            dataSoc.setSoTimeout(dataCfg.getIdleTime() * 1000);
+            LOG.debug("Passive data connection opened");
             }
-            dataSoc = ssoc;
-        } else {
-            LOG.debug("Opening active data connection");
-            dataSoc = new Socket();
-        }
-
-        dataSoc.setReuseAddress(true);
-
-        InetAddress localAddr = resolveAddress(dataConfig.getActiveLocalAddress());
-
-        // if no local address has been configured, make sure we use the same as the client connects from
-        if (localAddr == null) {
-            localAddr = ((InetSocketAddress) session.getLocalAddress()).getAddress();
-        }
-
-        SocketAddress localSocketAddress = new InetSocketAddress(localAddr, dataConfig.getActiveLocalPort());
-
-        LOG.debug("Binding active data connection to {}", localSocketAddress);
-        dataSoc.bind(localSocketAddress);
-
-        dataSoc.connect(new InetSocketAddress(address, port));
-        } else {
-
-        if (secure) {
-            LOG.debug("Opening secure passive data connection");
-            // this is where we wrap the unsecured socket as a SSLSocket. This is
-            // due to the JVM bug described in FTPSERVER-241.
-
-            // get server socket factory
-            SslConfiguration ssl = getSslConfiguration();
-
-            // we've already checked this, but let's do it again
-            if (ssl == null) {
-            throw new FtpException("Data connection SSL not configured");
-            }
-
-            SSLSocketFactory ssocketFactory = ssl.getSocketFactory();
-
-            Socket serverSocket = servSoc.accept();
-
-            SSLSocket sslSocket = (SSLSocket) ssocketFactory.createSocket(serverSocket, serverSocket.getInetAddress().getHostAddress(), serverSocket.getPort(), true);
-            sslSocket.setUseClientMode(false);
-
-            // initialize server socket
-            if (ssl.getClientAuth() == ClientAuth.NEED) {
-            sslSocket.setNeedClientAuth(true);
-            } else if (ssl.getClientAuth() == ClientAuth.WANT) {
-            sslSocket.setWantClientAuth(true);
-            }
-
-            if (ssl.getEnabledCipherSuites() != null) {
-            sslSocket.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
-            }
-
-            if (ssl.getEnabledProtocol() != null) {
-            sslSocket.setEnabledProtocols(new String[] { ssl.getEnabledProtocol() });
-            }
-
-            dataSoc = sslSocket;
-        } else {
-            LOG.debug("Opening passive data connection");
-
-            dataSoc = servSoc.accept();
-        }
-
-        if (dataConfig.isPassiveIpCheck()) {
-            // Let's make sure we got the connection from the same
-            // client that we are expecting
-            InetAddress remoteAddress = ((InetSocketAddress) session.getRemoteAddress()).getAddress();
-            InetAddress dataSocketAddress = dataSoc.getInetAddress();
-            if (!dataSocketAddress.equals(remoteAddress)) {
-            LOG.warn("Passive IP Check failed. Closing data connection from " + dataSocketAddress + " as it does not match the expected address " + remoteAddress);
+        } catch (Exception ex) {
             closeDataConnection();
-            return null;
-            }
+            LOG.warn("FtpDataConnection.getDataSocket()", ex);
+            throw ex;
         }
-
-        DataConnectionConfiguration dataCfg = session.getListener().getDataConnectionConfiguration();
-
-        dataSoc.setSoTimeout(dataCfg.getIdleTime() * 1000);
-        LOG.debug("Passive data connection opened");
+        dataSoc.setSoTimeout(dataConfig.getIdleTime() * 1000);
+    
+        // Make sure we initiate the SSL handshake, or we'll
+        // get an error if we turn out not to send any data
+        // e.g. during the listing of an empty directory
+        if (dataSoc instanceof SSLSocket) {
+            ((SSLSocket) dataSoc).startHandshake();
         }
-    } catch (Exception ex) {
-        closeDataConnection();
-        LOG.warn("FtpDataConnection.getDataSocket()", ex);
-        throw ex;
-    }
-    dataSoc.setSoTimeout(dataConfig.getIdleTime() * 1000);
-
-    // Make sure we initiate the SSL handshake, or we'll
-    // get an error if we turn out not to send any data
-    // e.g. during the listing of an empty directory
-    if (dataSoc instanceof SSLSocket) {
-        ((SSLSocket) dataSoc).startHandshake();
-    }
-
-    return dataSoc;
+    
+        return dataSoc;
     }
 
     /*
      * (non-Javadoc) Returns an InetAddress object from a hostname or IP address.
      */
     private InetAddress resolveAddress(String host) throws DataConnectionException {
-    if (host == null) {
-        return null;
-    } else {
-        try {
-        return InetAddress.getByName(host);
-        } catch (UnknownHostException ex) {
-        throw new DataConnectionException("Failed to resolve address", ex);
+        if (host == null) {
+            return null;
+        } else {
+            try {
+            return InetAddress.getByName(host);
+            } catch (UnknownHostException ex) {
+            throw new DataConnectionException("Failed to resolve address", ex);
+            }
         }
     }
-    }
 
     /*
      * (non-Javadoc)
diff --git a/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java b/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
index 0b1e5a7..cfa5d45 100644
--- a/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
+++ b/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
@@ -146,8 +146,8 @@
             ssl_filter.setWantClientAuth(true);
         }
 
-        if (ssl_conf.getEnabledProtocol() != null) {
-            ssl_filter.setEnabledProtocols(new String[] { ssl_conf.getEnabledProtocol() });
+        if (ssl_conf.getEnabledProtocols() != null) {
+            ssl_filter.setEnabledProtocols(ssl_conf.getEnabledProtocols());
         }
 
         if (ssl_conf.getEnabledCipherSuites() != null) {
diff --git a/core/src/main/java/org/apache/ftpserver/ssl/SslConfiguration.java b/core/src/main/java/org/apache/ftpserver/ssl/SslConfiguration.java
index c4da591..1a338ea 100644
--- a/core/src/main/java/org/apache/ftpserver/ssl/SslConfiguration.java
+++ b/core/src/main/java/org/apache/ftpserver/ssl/SslConfiguration.java
@@ -72,7 +72,7 @@
      * 
      * @return The name of the protocol as a String
      */
-    String getEnabledProtocol();
+    String[] getEnabledProtocols();
 
     /**
      * Return the required client authentication setting
diff --git a/core/src/main/java/org/apache/ftpserver/ssl/SslConfigurationFactory.java b/core/src/main/java/org/apache/ftpserver/ssl/SslConfigurationFactory.java
index b6778d7..6ee613a 100644
--- a/core/src/main/java/org/apache/ftpserver/ssl/SslConfigurationFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/ssl/SslConfigurationFactory.java
@@ -60,7 +60,7 @@
 
     private String trustStoreAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
 
-    private String sslProtocol = "TLS";
+    private String[] sslProtocols = new String[] {"TLSv1.2"};
 
     private ClientAuth clientAuth = ClientAuth.NONE;
 
@@ -158,20 +158,22 @@
      * 
      * @return The SSL protocol
      */
-    public String getSslProtocol() {
-    return sslProtocol;
+    public String[] getSslProtocols() {
+	return sslProtocols;
     }
 
     /**
-     * Set the SSL protocol used for this channel. Supported values are "SSL" and "TLS". Defaults to "TLS".
+     * Set the SSL protocols used for this channel. Defaults to "TLSv1.2".
      * 
-     * @param sslProtocol
-     *            The SSL protocol
+     * @param sslProtocols
+     *            The SSL protocols
      */
-    public void setSslProtocol(String sslProtocol) {
-    if (sslProtocol == null || sslProtocol.length() == 0)
-        throw new FtpServerConfigurationException("SslProcotol must not be null or zero length");
-    this.sslProtocol = sslProtocol;
+    public void setSslProtocol(String... sslProtocols) {
+        if (sslProtocols == null || sslProtocols.length == 0) {
+            throw new FtpServerConfigurationException("SslProcotol must not be null or zero length");
+        }
+        
+        this.sslProtocols = sslProtocols;
     }
 
     /**
@@ -182,13 +184,13 @@
      *            The desired authentication level
      */
     public void setClientAuthentication(String clientAuthReqd) {
-    if ("true".equalsIgnoreCase(clientAuthReqd) || "yes".equalsIgnoreCase(clientAuthReqd) || "need".equalsIgnoreCase(clientAuthReqd)) {
-        this.clientAuth = ClientAuth.NEED;
-    } else if ("want".equalsIgnoreCase(clientAuthReqd)) {
-        this.clientAuth = ClientAuth.WANT;
-    } else {
-        this.clientAuth = ClientAuth.NONE;
-    }
+        if ("true".equalsIgnoreCase(clientAuthReqd) || "yes".equalsIgnoreCase(clientAuthReqd) || "need".equalsIgnoreCase(clientAuthReqd)) {
+            this.clientAuth = ClientAuth.NEED;
+        } else if ("want".equalsIgnoreCase(clientAuthReqd)) {
+            this.clientAuth = ClientAuth.WANT;
+        } else {
+            this.clientAuth = ClientAuth.NONE;
+        }
     }
 
     /**
@@ -324,19 +326,22 @@
         KeyStore keyStore = loadStore(keystoreFile, keystoreType, keystorePass);
 
         KeyStore trustStore;
+        
         if (trustStoreFile != null) {
-        LOG.debug("Loading trust store from \"{}\", using the key store type \"{}\"", trustStoreFile.getAbsolutePath(), trustStoreType);
-        trustStore = loadStore(trustStoreFile, trustStoreType, trustStorePass);
+            LOG.debug("Loading trust store from \"{}\", using the key store type \"{}\"", trustStoreFile.getAbsolutePath(), trustStoreType);
+            trustStore = loadStore(trustStoreFile, trustStoreType, trustStorePass);
         } else {
-        trustStore = keyStore;
+            trustStore = keyStore;
         }
 
         String keyPassToUse;
+        
         if (keyPass == null) {
-        keyPassToUse = keystorePass;
+            keyPassToUse = keystorePass;
         } else {
-        keyPassToUse = keyPass;
+            keyPassToUse = keyPass;
         }
+        
         // initialize key manager factory
         KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(keystoreAlgorithm);
         keyManagerFactory.init(keyStore, keyPassToUse.toCharArray());
@@ -345,7 +350,8 @@
         TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(trustStoreAlgorithm);
         trustManagerFactory.init(trustStore);
 
-        return new DefaultSslConfiguration(keyManagerFactory, trustManagerFactory, clientAuth, sslProtocol, enabledCipherSuites, keyAlias);
+        return new DefaultSslConfiguration(keyManagerFactory, trustManagerFactory, clientAuth, sslProtocols, 
+        	enabledCipherSuites, keyAlias);
     } catch (Exception ex) {
         LOG.error("DefaultSsl.configure()", ex);
         throw new FtpServerConfigurationException("DefaultSsl.configure()", ex);
diff --git a/core/src/main/java/org/apache/ftpserver/ssl/impl/DefaultSslConfiguration.java b/core/src/main/java/org/apache/ftpserver/ssl/impl/DefaultSslConfiguration.java
index df960ef..9f17e9d 100644
--- a/core/src/main/java/org/apache/ftpserver/ssl/impl/DefaultSslConfiguration.java
+++ b/core/src/main/java/org/apache/ftpserver/ssl/impl/DefaultSslConfiguration.java
@@ -48,7 +48,7 @@
 
     private final TrustManagerFactory trustManagerFactory;
 
-    private String enabledProtocol = "TLS";
+    private String[] enabledProtocols = new String[] {"TLSv1.2"};
 
     private final ClientAuth clientAuth;// = ClientAuth.NONE;
 
@@ -65,78 +65,80 @@
      * 
      * @throws GeneralSecurityException
      */
-    public DefaultSslConfiguration(KeyManagerFactory keyManagerFactory, TrustManagerFactory trustManagerFactory, ClientAuth clientAuthReqd, String sslProtocol, String[] enabledCipherSuites, String keyAlias) throws GeneralSecurityException {
-    super();
-    this.clientAuth = clientAuthReqd;
-    this.enabledCipherSuites = enabledCipherSuites;
-    this.keyAlias = keyAlias;
-    this.keyManagerFactory = keyManagerFactory;
-    this.enabledProtocol = sslProtocol;
-    this.trustManagerFactory = trustManagerFactory;
-    this.sslContext = initContext();
-    this.socketFactory = sslContext.getSocketFactory();
+    public DefaultSslConfiguration(KeyManagerFactory keyManagerFactory, TrustManagerFactory trustManagerFactory, 
+	    ClientAuth clientAuthReqd, String[] sslProtocols, String[] enabledCipherSuites, String keyAlias) throws GeneralSecurityException {
+        super();
+        this.clientAuth = clientAuthReqd;
+        this.enabledCipherSuites = enabledCipherSuites;
+        this.keyAlias = keyAlias;
+        this.keyManagerFactory = keyManagerFactory;
+        this.enabledProtocols = sslProtocols;
+        this.trustManagerFactory = trustManagerFactory;
+        this.sslContext = initContext();
+        this.socketFactory = sslContext.getSocketFactory();
     }
 
     public SSLSocketFactory getSocketFactory() throws GeneralSecurityException {
-    return socketFactory;
+        return socketFactory;
     }
 
     /**
      * @see SslConfiguration#getSSLContext(String)
      */
-    public SSLContext getSSLContext(String protocol) throws GeneralSecurityException {
-    return sslContext;
+    public SSLContext getSSLContext(String enabledProtocol) throws GeneralSecurityException {
+        return sslContext;
     }
 
     /**
      * @see SslConfiguration#getEnabledProtocol()
      */
-    public String getEnabledProtocol() {
-    return enabledProtocol;
+    public String[] getEnabledProtocols() {
+        return enabledProtocols;
     }
 
     /**
      * @see SslConfiguration#getClientAuth()
      */
     public ClientAuth getClientAuth() {
-    return clientAuth;
+        return clientAuth;
     }
 
     /**
      * @see SslConfiguration#getSSLContext()
      */
     public SSLContext getSSLContext() throws GeneralSecurityException {
-    return getSSLContext(enabledProtocol);
+        return getSSLContext(enabledProtocols[0]);
     }
 
     /**
      * @see SslConfiguration#getEnabledCipherSuites()
      */
     public String[] getEnabledCipherSuites() {
-    if (enabledCipherSuites != null) {
-        return enabledCipherSuites.clone();
-    } else {
-        return null;
-    }
-    }
-
-    private SSLContext initContext() throws GeneralSecurityException {
-    KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
-
-    // wrap key managers to allow us to control their behavior
-    // (FTPSERVER-93)
-    for (int i = 0; i < keyManagers.length; i++) {
-        if (ClassUtils.extendsClass(keyManagers[i].getClass(), "javax.net.ssl.X509ExtendedKeyManager")) {
-        keyManagers[i] = new ExtendedAliasKeyManager(keyManagers[i], keyAlias);
-        } else if (keyManagers[i] instanceof X509KeyManager) {
-        keyManagers[i] = new AliasKeyManager(keyManagers[i], keyAlias);
+        if (enabledCipherSuites != null) {
+            return enabledCipherSuites.clone();
+        } else {
+            return null;
         }
     }
 
-    // create and initialize the SSLContext
-    SSLContext ctx = SSLContext.getInstance(enabledProtocol);
-    ctx.init(keyManagers, trustManagerFactory.getTrustManagers(), null);
-    // Create the socket factory
-    return ctx;
+    private SSLContext initContext() throws GeneralSecurityException {
+        KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
+    
+        // wrap key managers to allow us to control their behavior
+        // (FTPSERVER-93)
+        for (int i = 0; i < keyManagers.length; i++) {
+            if (ClassUtils.extendsClass(keyManagers[i].getClass(), "javax.net.ssl.X509ExtendedKeyManager")) {
+                keyManagers[i] = new ExtendedAliasKeyManager(keyManagers[i], keyAlias);
+            } else if (keyManagers[i] instanceof X509KeyManager) {
+                keyManagers[i] = new AliasKeyManager(keyManagers[i], keyAlias);
+            }
+        }
+    
+        // create and initialize the SSLContext
+        SSLContext ctx = SSLContext.getInstance(enabledProtocols[0]);
+        ctx.init(keyManagers, trustManagerFactory.getTrustManagers(), null);
+        
+        // Create the socket factory
+        return ctx;
     }
 }
diff --git a/core/src/main/java/org/apache/ftpserver/util/StringUtils.java b/core/src/main/java/org/apache/ftpserver/util/StringUtils.java
index 8642079..7bba65d 100644
--- a/core/src/main/java/org/apache/ftpserver/util/StringUtils.java
+++ b/core/src/main/java/org/apache/ftpserver/util/StringUtils.java
@@ -28,12 +28,20 @@
  *
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
-public class StringUtils {
+public final class StringUtils {
+    private StringUtils() {
+        // Nothing to do
+    }
 
     /**
      * This is a string replacement method.
+     *
+     * @param source The original string
+     * @param oldStr The substring to replace
+     * @param newStr The replacement string
+     * @return The modified string
      */
-    public static final String replaceString(String source, String oldStr,
+    public static String replaceString(String source, String oldStr,
             String newStr) {
         StringBuilder sb = new StringBuilder(source.length());
         int sind = 0;
@@ -48,9 +56,19 @@
     }
 
     /**
-     * Replace string.
+     * Replace strings using placeholders. Each occurence of {} in the original
+     * string will be replaced with the object at the same index. For instance:
+     * <br>
+     * <code>replaceString( "This {} a {}", ["is', "string"])</code><br>
+     * will produce:<br>
+     * <code>"This is a string"</code><br>
+     *
+     * @param source The original string
+     * @param args The array of object to replace the placeholders in
+     * the original string
+     * @return The modified string
      */
-    public static final String replaceString(String source, Object[] args) {
+    public static String replaceString(String source, Object[] args) {
         int startIndex = 0;
         int openIndex = source.indexOf('{', startIndex);
         if (openIndex == -1) {
@@ -87,9 +105,19 @@
     }
 
     /**
-     * Replace string.
+     * Replace strings using placeholders. Each occurence of {} in the original
+     * string will be replaced with the object at the same index. For instance:
+     * <br>
+     * <code>replaceString( "This {} a {}", Map("is', "string"))</code><br>
+     * will produce:<br>
+     * <code>"This is a string"</code><br>
+     *
+     * @param source The original string
+     * @param args The map of object to replace the placeholders in
+     * the original string
+     * @return The modified string
      */
-    public static final String replaceString(String source,
+    public static String replaceString(String source,
             Map<String, Object> args) {
         int startIndex = 0;
         int openIndex = source.indexOf('{', startIndex);
@@ -129,15 +157,15 @@
     }
 
     /**
-         * This method is used to insert HTML block dynamically.
-         *
-         * @param source the HTML code to be processes
-         * @param bReplaceNl if true '\n' will be replaced by <br>
-         * @param bReplaceTag if true '<' will be replaced by &lt; and
-         *                          '>' will be replaced by &gt;
-         * @param bReplaceQuote if true '\"' will be replaced by &quot;
-         */
-    public static final String formatHtml(String source, boolean bReplaceNl,
+     * This method is used to insert HTML block dynamically.
+     *
+     * @param source the HTML code to be processes
+     * @param bReplaceNl if true '\n' will be replaced by <br>
+     * @param bReplaceTag if true '<' will be replaced by &lt; and
+     *                          '>' will be replaced by &gt;
+     * @param bReplaceQuote if true '\"' will be replaced by &quot;
+     */
+    public static String formatHtml(String source, boolean bReplaceNl,
             boolean bReplaceTag, boolean bReplaceQuote) {
 
         StringBuilder sb = new StringBuilder();
@@ -169,7 +197,7 @@
                     } else {
                         sb.append(c);
                     }
-                    
+
                     break;
 
                 case '\n':
@@ -203,7 +231,7 @@
     /**
      * Pad string object.
      */
-    public static final String pad(String src, char padChar, boolean rightPad,
+    public static String pad(String src, char padChar, boolean rightPad,
             int totalLength) {
 
         int srcLength = src.length();
@@ -227,7 +255,7 @@
     /**
      * Get hex string from byte array.
      */
-    public static final String toHexString(byte[] res) {
+    public static String toHexString(byte[] res) {
         StringBuilder sb = new StringBuilder(res.length << 1);
         for (int i = 0; i < res.length; i++) {
             String digit = Integer.toHexString(0xFF & res[i]);
@@ -242,7 +270,7 @@
     /**
      * Get byte array from hex string.
      */
-    public static final byte[] toByteArray(String hexString) {
+    public static byte[] toByteArray(String hexString) {
         int arrLength = hexString.length() >> 1;
         byte buff[] = new byte[arrLength];
         for (int i = 0; i < arrLength; i++) {
diff --git a/core/src/test/resources/spring-config/config-property-placeholder.xml b/core/src/test/resources/spring-config/config-property-placeholder.xml
index 49ee22d..e32682d 100644
--- a/core/src/test/resources/spring-config/config-property-placeholder.xml
+++ b/core/src/test/resources/spring-config/config-property-placeholder.xml
@@ -24,7 +24,7 @@
     xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
-       http://mina.apache.org/ftpserver/spring/v1 http://mina.apache.org/ftpserver/ftpserver-1.0.xsd    
+       http://mina.apache.org/ftpserver/spring/v1 https://mina.apache.org/ftpserver-project/ftpserver-1.0.xsd    
        ">
   <context:property-placeholder location="src/test/resources/spring-config/placeholder.properties"/>
     
diff --git a/core/src/test/resources/spring-config/config-spring-1.xml b/core/src/test/resources/spring-config/config-spring-1.xml
index b836cf6..d5bf7f9 100644
--- a/core/src/test/resources/spring-config/config-spring-1.xml
+++ b/core/src/test/resources/spring-config/config-spring-1.xml
@@ -21,9 +21,10 @@
   xmlns:beans="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
-     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
-     http://mina.apache.org/ftpserver/spring/v1 http://mina.apache.org/ftpserver/ftpserver-1.0.xsd  
-     "
+     http://www.springframework.org/schema/beans 
+     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
+     http://mina.apache.org/ftpserver/spring/v1 
+     https://mina.apache.org/ftpserver-project/ftpserver-1.0.xsd"
      max-logins="500"
      anon-enabled="false"
      max-anon-logins="123"
@@ -31,12 +32,11 @@
      login-failure-delay="125"
      >
 
-
   <listeners>
     <nio-listener name="listener0" port="2222" local-address="1.2.3.4">
-              <ssl>
-                  <keystore file="src/test/resources/ftpserver.jks" password="password"/>
-              </ssl>
+      <ssl>
+        <keystore file="src/test/resources/ftpserver.jks" password="password"/>
+      </ssl>
 
       <data-connection idle-timeout="100" implicit-ssl="true">
         <active enabled="true" local-address="1.2.3.4"/>
@@ -44,6 +44,7 @@
       </data-connection>
       <blacklist>1.2.3.0/16, 1.2.4.0/16, 1.2.3.4</blacklist>        
     </nio-listener>
+    
     <listener name="listener1">
       <beans:bean id="listener1" class="org.apache.ftpserver.config.spring.MyCustomListener">
         <beans:property name="port" value="2223"/>
@@ -75,7 +76,9 @@
   <user-manager>
     <beans:bean class="org.apache.ftpserver.config.spring.MockUserManager"/>
   </user-manager>
+  
   <native-filesystem case-insensitive="true" create-home="true" />
+  
   <commands use-default="false">
     <command name="FOO">
       <beans:bean class="org.apache.ftpserver.command.impl.HELP" />
diff --git a/distribution/res/conf/ftpd-full.xml b/distribution/res/conf/ftpd-full.xml
index 747ee14..8f690c7 100644
--- a/distribution/res/conf/ftpd-full.xml
+++ b/distribution/res/conf/ftpd-full.xml
@@ -17,7 +17,7 @@
   xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
-     http://mina.apache.org/ftpserver/spring/v1 http://mina.apache.org/ftpserver/ftpserver-1.0.xsd  
+     http://mina.apache.org/ftpserver/spring/v1 https://mina.apache.org/ftpserver-project/ftpserver-1.0.xsd  
      "
   id="myServer">
   <!--
@@ -33,8 +33,7 @@
         <truststore file="mytruststore.jks" password="secret" />
       </ssl>
       <data-connection idle-timeout="60">
-        <active enabled="true" local-address="1.2.3.4" local-port="2323"
-          ip-check="true" />
+        <active enabled="true" local-address="1.2.3.4" local-port="2323" ip-check="true" />
         <passive ports="123-125" address="1.2.3.4" external-address="1.2.3.4" />
       </data-connection>
       <blacklist>1.2.3.0/16, 1.2.4.0/16, 1.2.3.4</blacklist>
diff --git a/distribution/res/conf/ftpd-typical.xml b/distribution/res/conf/ftpd-typical.xml
index 68f3569..d78db46 100644
--- a/distribution/res/conf/ftpd-typical.xml
+++ b/distribution/res/conf/ftpd-typical.xml
@@ -16,7 +16,7 @@
 <server xmlns="http://mina.apache.org/ftpserver/spring/v1"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
-     http://mina.apache.org/ftpserver/spring/v1 http://mina.apache.org/ftpserver-project/ftpserver-1.0.xsd  
+     http://mina.apache.org/ftpserver/spring/v1 https://mina.apache.org/ftpserver-project/ftpserver-1.0.xsd  
      "
   id="myServer">
   <listeners>