o Formating (mainly replacing tabs by spaces)
o Fix applied for FTPSERVER-475
o Made SSLv3 accepted in tests in order to have them working with Java 8

diff --git a/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java b/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java
index 330c387..c09bf57 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java
@@ -50,7 +50,6 @@
 import org.apache.mina.core.write.WriteRequest;
 import org.apache.mina.core.write.WriteRequestQueue;
 import org.apache.mina.filter.ssl.SslFilter;
-
 import org.slf4j.LoggerFactory;
 
 /**
@@ -66,36 +65,36 @@
      */
     public static final String ATTRIBUTE_PREFIX = "org.apache.ftpserver.";
     private static final String ATTRIBUTE_USER_ARGUMENT = ATTRIBUTE_PREFIX
-	    + "user-argument";
+            + "user-argument";
     private static final String ATTRIBUTE_SESSION_ID = ATTRIBUTE_PREFIX
-	    + "session-id";
+            + "session-id";
     private static final String ATTRIBUTE_USER = ATTRIBUTE_PREFIX + "user";
     private static final String ATTRIBUTE_LANGUAGE = ATTRIBUTE_PREFIX
-	    + "language";
+            + "language";
     private static final String ATTRIBUTE_LOGIN_TIME = ATTRIBUTE_PREFIX
-	    + "login-time";
+            + "login-time";
     private static final String ATTRIBUTE_DATA_CONNECTION = ATTRIBUTE_PREFIX
-	    + "data-connection";
+            + "data-connection";
     private static final String ATTRIBUTE_FILE_SYSTEM = ATTRIBUTE_PREFIX
-	    + "file-system";
+            + "file-system";
     private static final String ATTRIBUTE_RENAME_FROM = ATTRIBUTE_PREFIX
-	    + "rename-from";
+            + "rename-from";
     private static final String ATTRIBUTE_FILE_OFFSET = ATTRIBUTE_PREFIX
-	    + "file-offset";
+            + "file-offset";
     private static final String ATTRIBUTE_DATA_TYPE = ATTRIBUTE_PREFIX
-	    + "data-type";
+            + "data-type";
     private static final String ATTRIBUTE_STRUCTURE = ATTRIBUTE_PREFIX
-	    + "structure";
+            + "structure";
     private static final String ATTRIBUTE_FAILED_LOGINS = ATTRIBUTE_PREFIX
-	    + "failed-logins";
+            + "failed-logins";
     private static final String ATTRIBUTE_LISTENER = ATTRIBUTE_PREFIX
-	    + "listener";
+            + "listener";
     private static final String ATTRIBUTE_MAX_IDLE_TIME = ATTRIBUTE_PREFIX
-	    + "max-idle-time";
+            + "max-idle-time";
     private static final String ATTRIBUTE_LAST_ACCESS_TIME = ATTRIBUTE_PREFIX
-	    + "last-access-time";
+            + "last-access-time";
     private static final String ATTRIBUTE_CACHED_REMOTE_ADDRESS = ATTRIBUTE_PREFIX
-	    + "cached-remote-address";
+            + "cached-remote-address";
     private final IoSession wrappedSession;
     private final FtpServerContext context;
     /**
@@ -108,21 +107,37 @@
      * @see IoSession#close()
      */
     public CloseFuture close() {
-	return wrappedSession.close();
+        return wrappedSession.close();
     }
 
     /**
      * @see IoSession#close(boolean)
      */
     public CloseFuture close(boolean immediately) {
-	return wrappedSession.close(immediately);
+        return wrappedSession.close(immediately);
+    }
+
+    /**
+     * @see IoSession#closeNow()
+     */
+    public CloseFuture closeNow()
+    {
+        return wrappedSession.closeNow();
+    }
+
+    /**
+     * @see IoSession#closeOnFlush()
+     */
+    public CloseFuture closeOnFlush()
+    {
+        return wrappedSession.closeOnFlush();
     }
 
     /**
      * @see IoSession#containsAttribute(Object)
      */
     public boolean containsAttribute(Object key) {
-	return wrappedSession.containsAttribute(key);
+        return wrappedSession.containsAttribute(key);
     }
 
     /**
@@ -130,325 +145,332 @@
      */
     @SuppressWarnings("deprecation")
     public Object getAttachment() {
-	return wrappedSession.getAttachment();
+        return wrappedSession.getAttachment();
     }
 
     /**
      * @see IoSession#getAttribute(Object)
      */
     public Object getAttribute(Object key) {
-	return wrappedSession.getAttribute(key);
+        return wrappedSession.getAttribute(key);
     }
 
     /**
      * @see IoSession#getAttribute(Object, Object)
      */
     public Object getAttribute(Object key, Object defaultValue) {
-	return wrappedSession.getAttribute(key, defaultValue);
+        return wrappedSession.getAttribute(key, defaultValue);
     }
 
     /**
      * @see IoSession#getAttributeKeys()
      */
     public Set<Object> getAttributeKeys() {
-	return wrappedSession.getAttributeKeys();
+        return wrappedSession.getAttributeKeys();
     }
 
     /**
      * @see IoSession#getBothIdleCount()
      */
     public int getBothIdleCount() {
-	return wrappedSession.getBothIdleCount();
+        return wrappedSession.getBothIdleCount();
     }
 
     /**
      * @see IoSession#getCloseFuture()
      */
     public CloseFuture getCloseFuture() {
-	return wrappedSession.getCloseFuture();
+        return wrappedSession.getCloseFuture();
     }
 
     /**
      * @see IoSession#getConfig()
      */
     public IoSessionConfig getConfig() {
-	return wrappedSession.getConfig();
+        return wrappedSession.getConfig();
     }
 
     /**
      * @see IoSession#getCreationTime()
      */
     public long getCreationTime() {
-	return wrappedSession.getCreationTime();
+        return wrappedSession.getCreationTime();
     }
 
     /**
      * @see IoSession#getFilterChain()
      */
     public IoFilterChain getFilterChain() {
-	return wrappedSession.getFilterChain();
+        return wrappedSession.getFilterChain();
     }
 
     /**
      * @see IoSession#getHandler()
      */
     public IoHandler getHandler() {
-	return wrappedSession.getHandler();
+        return wrappedSession.getHandler();
     }
 
     /**
      * @see IoSession#getId()
      */
     public long getId() {
-	return wrappedSession.getId();
+        return wrappedSession.getId();
     }
 
     /**
      * @see IoSession#getIdleCount(IdleStatus)
      */
     public int getIdleCount(IdleStatus status) {
-	return wrappedSession.getIdleCount(status);
+        return wrappedSession.getIdleCount(status);
     }
 
     /**
      * @see IoSession#getLastBothIdleTime()
      */
     public long getLastBothIdleTime() {
-	return wrappedSession.getLastBothIdleTime();
+        return wrappedSession.getLastBothIdleTime();
     }
 
     /**
      * @see IoSession#getLastIdleTime(IdleStatus)
      */
     public long getLastIdleTime(IdleStatus status) {
-	return wrappedSession.getLastIdleTime(status);
+        return wrappedSession.getLastIdleTime(status);
     }
 
     /**
      * @see IoSession#getLastIoTime()
      */
     public long getLastIoTime() {
-	return wrappedSession.getLastIoTime();
+        return wrappedSession.getLastIoTime();
     }
 
     /**
      * @see IoSession#getLastReadTime()
      */
     public long getLastReadTime() {
-	return wrappedSession.getLastReadTime();
+        return wrappedSession.getLastReadTime();
     }
 
     /**
      * @see IoSession#getLastReaderIdleTime()
      */
     public long getLastReaderIdleTime() {
-	return wrappedSession.getLastReaderIdleTime();
+        return wrappedSession.getLastReaderIdleTime();
     }
 
     /**
      * @see IoSession#getLastWriteTime()
      */
     public long getLastWriteTime() {
-	return wrappedSession.getLastWriteTime();
+        return wrappedSession.getLastWriteTime();
     }
 
     /**
      * @see IoSession#getLastWriterIdleTime()
      */
     public long getLastWriterIdleTime() {
-	return wrappedSession.getLastWriterIdleTime();
+        return wrappedSession.getLastWriterIdleTime();
     }
 
     /**
      * @see IoSession#getLocalAddress()
      */
     public SocketAddress getLocalAddress() {
-	return wrappedSession.getLocalAddress();
+        return wrappedSession.getLocalAddress();
     }
 
     /**
      * @see IoSession#getReadBytes()
      */
     public long getReadBytes() {
-	return wrappedSession.getReadBytes();
+        return wrappedSession.getReadBytes();
     }
 
     /**
      * @see IoSession#getReadBytesThroughput()
      */
     public double getReadBytesThroughput() {
-	return wrappedSession.getReadBytesThroughput();
+        return wrappedSession.getReadBytesThroughput();
     }
 
     /**
      * @see IoSession#getReadMessages()
      */
     public long getReadMessages() {
-	return wrappedSession.getReadMessages();
+        return wrappedSession.getReadMessages();
     }
 
     /**
      * @see IoSession#getReadMessagesThroughput()
      */
     public double getReadMessagesThroughput() {
-	return wrappedSession.getReadMessagesThroughput();
+        return wrappedSession.getReadMessagesThroughput();
     }
 
     /**
      * @see IoSession#getReaderIdleCount()
      */
     public int getReaderIdleCount() {
-	return wrappedSession.getReaderIdleCount();
+        return wrappedSession.getReaderIdleCount();
     }
 
     /**
      * @see IoSession#getRemoteAddress()
      */
     public SocketAddress getRemoteAddress() {
-	// when closing a socket, the remote address might be reset to null
-	// therefore, we attempt to keep a cached copy around
+        // when closing a socket, the remote address might be reset to null
+        // therefore, we attempt to keep a cached copy around
 
-	SocketAddress address = wrappedSession.getRemoteAddress();
-	if (address == null
-		&& containsAttribute(ATTRIBUTE_CACHED_REMOTE_ADDRESS)) {
-	    return (SocketAddress) getAttribute(ATTRIBUTE_CACHED_REMOTE_ADDRESS);
-	} else {
-	    setAttribute(ATTRIBUTE_CACHED_REMOTE_ADDRESS, address);
-	    return address;
-	}
+        SocketAddress address = wrappedSession.getRemoteAddress();
+        if (address == null
+                && containsAttribute(ATTRIBUTE_CACHED_REMOTE_ADDRESS)) {
+            return (SocketAddress) getAttribute(ATTRIBUTE_CACHED_REMOTE_ADDRESS);
+        } else {
+            setAttribute(ATTRIBUTE_CACHED_REMOTE_ADDRESS, address);
+            return address;
+        }
     }
 
     /**
      * @see IoSession#getScheduledWriteBytes()
      */
     public long getScheduledWriteBytes() {
-	return wrappedSession.getScheduledWriteBytes();
+        return wrappedSession.getScheduledWriteBytes();
     }
 
     /**
      * @see IoSession#getScheduledWriteMessages()
      */
     public int getScheduledWriteMessages() {
-	return wrappedSession.getScheduledWriteMessages();
+        return wrappedSession.getScheduledWriteMessages();
     }
 
     /**
      * @see IoSession#getService()
      */
     public IoService getService() {
-	return wrappedSession.getService();
+        return wrappedSession.getService();
     }
 
     /**
      * @see IoSession#getServiceAddress()
      */
     public SocketAddress getServiceAddress() {
-	return wrappedSession.getServiceAddress();
+        return wrappedSession.getServiceAddress();
     }
 
     /**
      * @see IoSession#getTransportMetadata()
      */
     public TransportMetadata getTransportMetadata() {
-	return wrappedSession.getTransportMetadata();
+        return wrappedSession.getTransportMetadata();
     }
 
     /**
      * @see IoSession#getWriterIdleCount()
      */
     public int getWriterIdleCount() {
-	return wrappedSession.getWriterIdleCount();
+        return wrappedSession.getWriterIdleCount();
     }
 
     /**
      * @see IoSession#getWrittenBytes()
      */
     public long getWrittenBytes() {
-	return wrappedSession.getWrittenBytes();
+        return wrappedSession.getWrittenBytes();
     }
 
     /**
      * @see IoSession#getWrittenBytesThroughput()
      */
     public double getWrittenBytesThroughput() {
-	return wrappedSession.getWrittenBytesThroughput();
+        return wrappedSession.getWrittenBytesThroughput();
     }
 
     /**
      * @see IoSession#getWrittenMessages()
      */
     public long getWrittenMessages() {
-	return wrappedSession.getWrittenMessages();
+        return wrappedSession.getWrittenMessages();
     }
 
     /**
      * @see IoSession#getWrittenMessagesThroughput()
      */
     public double getWrittenMessagesThroughput() {
-	return wrappedSession.getWrittenMessagesThroughput();
+        return wrappedSession.getWrittenMessagesThroughput();
     }
 
     /**
      * @see IoSession#isClosing()
      */
     public boolean isClosing() {
-	return wrappedSession.isClosing();
+        return wrappedSession.isClosing();
     }
 
     /**
      * @see IoSession#isConnected()
      */
     public boolean isConnected() {
-	return wrappedSession.isConnected();
+        return wrappedSession.isConnected();
+    }
+
+    /**
+     * @see IoSession#isActive()
+     */
+    public boolean isActive() {
+        return wrappedSession.isActive();
     }
 
     /**
      * @see IoSession#isIdle(IdleStatus)
      */
     public boolean isIdle(IdleStatus status) {
-	return wrappedSession.isIdle(status);
+        return wrappedSession.isIdle(status);
     }
 
     /**
      * @see IoSession#read()
      */
     public ReadFuture read() {
-	return wrappedSession.read();
+        return wrappedSession.read();
     }
 
     /**
      * @see IoSession#removeAttribute(Object)
      */
     public Object removeAttribute(Object key) {
-	return wrappedSession.removeAttribute(key);
+        return wrappedSession.removeAttribute(key);
     }
 
     /**
      * @see IoSession#removeAttribute(Object, Object)
      */
     public boolean removeAttribute(Object key, Object value) {
-	return wrappedSession.removeAttribute(key, value);
+        return wrappedSession.removeAttribute(key, value);
     }
 
     /**
      * @see IoSession#replaceAttribute(Object, Object, Object)
      */
     public boolean replaceAttribute(Object key, Object oldValue, Object newValue) {
-	return wrappedSession.replaceAttribute(key, oldValue, newValue);
+        return wrappedSession.replaceAttribute(key, oldValue, newValue);
     }
 
     /**
      * @see IoSession#resumeRead()
      */
     public void resumeRead() {
-	wrappedSession.resumeRead();
+        wrappedSession.resumeRead();
     }
 
     /**
      * @see IoSession#resumeWrite()
      */
     public void resumeWrite() {
-	wrappedSession.resumeWrite();
+        wrappedSession.resumeWrite();
     }
 
     /**
@@ -456,216 +478,216 @@
      */
     @SuppressWarnings("deprecation")
     public Object setAttachment(Object attachment) {
-	return wrappedSession.setAttachment(attachment);
+        return wrappedSession.setAttachment(attachment);
     }
 
     /**
      * @see IoSession#setAttribute(Object)
      */
     public Object setAttribute(Object key) {
-	return wrappedSession.setAttribute(key);
+        return wrappedSession.setAttribute(key);
     }
 
     /**
      * @see IoSession#setAttribute(Object, Object)
      */
     public Object setAttribute(Object key, Object value) {
-	return wrappedSession.setAttribute(key, value);
+        return wrappedSession.setAttribute(key, value);
     }
 
     /**
      * @see IoSession#setAttributeIfAbsent(Object)
      */
     public Object setAttributeIfAbsent(Object key) {
-	return wrappedSession.setAttributeIfAbsent(key);
+        return wrappedSession.setAttributeIfAbsent(key);
     }
 
     /**
      * @see IoSession#setAttributeIfAbsent(Object, Object)
      */
     public Object setAttributeIfAbsent(Object key, Object value) {
-	return wrappedSession.setAttributeIfAbsent(key, value);
+        return wrappedSession.setAttributeIfAbsent(key, value);
     }
 
     /**
      * @see IoSession#suspendRead()
      */
     public void suspendRead() {
-	wrappedSession.suspendRead();
+        wrappedSession.suspendRead();
     }
 
     /**
      * @see IoSession#suspendWrite()
      */
     public void suspendWrite() {
-	wrappedSession.suspendWrite();
+        wrappedSession.suspendWrite();
     }
 
     /**
      * @see IoSession#write(Object)
      */
     public WriteFuture write(Object message) {
-	WriteFuture future = wrappedSession.write(message);
-	this.lastReply = (FtpReply) message;
-	return future;
+        WriteFuture future = wrappedSession.write(message);
+        this.lastReply = (FtpReply) message;
+        return future;
     }
 
     /**
      * @see IoSession#write(Object, SocketAddress)
      */
     public WriteFuture write(Object message, SocketAddress destination) {
-	WriteFuture future = wrappedSession.write(message, destination);
-	this.lastReply = (FtpReply) message;
-	return future;
+        WriteFuture future = wrappedSession.write(message, destination);
+        this.lastReply = (FtpReply) message;
+        return future;
     }
 
     /* End wrapped IoSession methods */
     public void resetState() {
-	removeAttribute(ATTRIBUTE_RENAME_FROM);
-	removeAttribute(ATTRIBUTE_FILE_OFFSET);
+        removeAttribute(ATTRIBUTE_RENAME_FROM);
+        removeAttribute(ATTRIBUTE_FILE_OFFSET);
     }
 
     public synchronized ServerDataConnectionFactory getDataConnection() {
-	if (containsAttribute(ATTRIBUTE_DATA_CONNECTION)) {
-	    return (ServerDataConnectionFactory) getAttribute(ATTRIBUTE_DATA_CONNECTION);
-	} else {
-	    IODataConnectionFactory dataCon = new IODataConnectionFactory(
-		    context, this);
-	    dataCon.setServerControlAddress(((InetSocketAddress) getLocalAddress()).getAddress());
-	    setAttribute(ATTRIBUTE_DATA_CONNECTION, dataCon);
+        if (containsAttribute(ATTRIBUTE_DATA_CONNECTION)) {
+            return (ServerDataConnectionFactory) getAttribute(ATTRIBUTE_DATA_CONNECTION);
+        } else {
+            IODataConnectionFactory dataCon = new IODataConnectionFactory(
+                    context, this);
+            dataCon.setServerControlAddress(((InetSocketAddress) getLocalAddress()).getAddress());
+            setAttribute(ATTRIBUTE_DATA_CONNECTION, dataCon);
 
-	    return dataCon;
-	}
+            return dataCon;
+        }
     }
 
     public FileSystemView getFileSystemView() {
-	return (FileSystemView) getAttribute(ATTRIBUTE_FILE_SYSTEM);
+        return (FileSystemView) getAttribute(ATTRIBUTE_FILE_SYSTEM);
     }
 
     public User getUser() {
-	return (User) getAttribute(ATTRIBUTE_USER);
+        return (User) getAttribute(ATTRIBUTE_USER);
     }
 
     /**
      * Is logged-in
      */
     public boolean isLoggedIn() {
-	return containsAttribute(ATTRIBUTE_USER);
+        return containsAttribute(ATTRIBUTE_USER);
     }
 
     public Listener getListener() {
-	return (Listener) getAttribute(ATTRIBUTE_LISTENER);
+        return (Listener) getAttribute(ATTRIBUTE_LISTENER);
     }
 
     public void setListener(Listener listener) {
-	setAttribute(ATTRIBUTE_LISTENER, listener);
+        setAttribute(ATTRIBUTE_LISTENER, listener);
     }
 
     public FtpSession getFtpletSession() {
-	return new DefaultFtpSession(this);
+        return new DefaultFtpSession(this);
     }
 
     public String getLanguage() {
-	return (String) getAttribute(ATTRIBUTE_LANGUAGE);
+        return (String) getAttribute(ATTRIBUTE_LANGUAGE);
     }
 
     public void setLanguage(String language) {
-	setAttribute(ATTRIBUTE_LANGUAGE, language);
+        setAttribute(ATTRIBUTE_LANGUAGE, language);
 
     }
 
     public String getUserArgument() {
-	return (String) getAttribute(ATTRIBUTE_USER_ARGUMENT);
+        return (String) getAttribute(ATTRIBUTE_USER_ARGUMENT);
     }
 
     public void setUser(User user) {
-	setAttribute(ATTRIBUTE_USER, user);
+        setAttribute(ATTRIBUTE_USER, user);
 
     }
 
     public void setUserArgument(String userArgument) {
-	setAttribute(ATTRIBUTE_USER_ARGUMENT, userArgument);
+        setAttribute(ATTRIBUTE_USER_ARGUMENT, userArgument);
 
     }
 
     public int getMaxIdleTime() {
-	return (Integer) getAttribute(ATTRIBUTE_MAX_IDLE_TIME, 0);
+        return (Integer) getAttribute(ATTRIBUTE_MAX_IDLE_TIME, 0);
     }
 
     public void setMaxIdleTime(int maxIdleTime) {
-	setAttribute(ATTRIBUTE_MAX_IDLE_TIME, maxIdleTime);
+        setAttribute(ATTRIBUTE_MAX_IDLE_TIME, maxIdleTime);
 
-	int listenerTimeout = getListener().getIdleTimeout();
+        int listenerTimeout = getListener().getIdleTimeout();
 
-	// the listener timeout should be the upper limit, unless set to unlimited
-	// if the user limit is set to be unlimited, use the listener value is the threshold
-	//     (already used as the default for all sessions)
-	// else, if the user limit is less than the listener idle time, use the user limit
-	if (listenerTimeout <= 0
-		|| (maxIdleTime > 0 && maxIdleTime < listenerTimeout)) {
-	    wrappedSession.getConfig().setBothIdleTime(maxIdleTime);
-	}
+        // the listener timeout should be the upper limit, unless set to unlimited
+        // if the user limit is set to be unlimited, use the listener value is the threshold
+        //     (already used as the default for all sessions)
+        // else, if the user limit is less than the listener idle time, use the user limit
+        if (listenerTimeout <= 0
+                || (maxIdleTime > 0 && maxIdleTime < listenerTimeout)) {
+            wrappedSession.getConfig().setBothIdleTime(maxIdleTime);
+        }
     }
 
     public synchronized void increaseFailedLogins() {
-	int failedLogins = (Integer) getAttribute(ATTRIBUTE_FAILED_LOGINS, 0);
-	failedLogins++;
-	setAttribute(ATTRIBUTE_FAILED_LOGINS, failedLogins);
+        int failedLogins = (Integer) getAttribute(ATTRIBUTE_FAILED_LOGINS, 0);
+        failedLogins++;
+        setAttribute(ATTRIBUTE_FAILED_LOGINS, failedLogins);
     }
 
     public int getFailedLogins() {
-	return (Integer) getAttribute(ATTRIBUTE_FAILED_LOGINS, 0);
+        return (Integer) getAttribute(ATTRIBUTE_FAILED_LOGINS, 0);
     }
 
     public void setLogin(FileSystemView fsview) {
-	setAttribute(ATTRIBUTE_LOGIN_TIME, new Date());
-	setAttribute(ATTRIBUTE_FILE_SYSTEM, fsview);
+        setAttribute(ATTRIBUTE_LOGIN_TIME, new Date());
+        setAttribute(ATTRIBUTE_FILE_SYSTEM, fsview);
     }
 
     public void reinitialize() {
-	logoutUser();
-	removeAttribute(ATTRIBUTE_USER);
-	removeAttribute(ATTRIBUTE_USER_ARGUMENT);
-	removeAttribute(ATTRIBUTE_LOGIN_TIME);
-	removeAttribute(ATTRIBUTE_FILE_SYSTEM);
-	removeAttribute(ATTRIBUTE_RENAME_FROM);
-	removeAttribute(ATTRIBUTE_FILE_OFFSET);
+        logoutUser();
+        removeAttribute(ATTRIBUTE_USER);
+        removeAttribute(ATTRIBUTE_USER_ARGUMENT);
+        removeAttribute(ATTRIBUTE_LOGIN_TIME);
+        removeAttribute(ATTRIBUTE_FILE_SYSTEM);
+        removeAttribute(ATTRIBUTE_RENAME_FROM);
+        removeAttribute(ATTRIBUTE_FILE_OFFSET);
     }
 
     public void logoutUser() {
-	ServerFtpStatistics stats = ((ServerFtpStatistics) context.getFtpStatistics());
-	if (stats != null) {
-	    stats.setLogout(this);
-	    LoggerFactory.getLogger(this.getClass()).debug("Statistics login decreased due to user logout");
-	} else {
-	    LoggerFactory.getLogger(this.getClass()).warn("Statistics not available in session, can not decrease login  count");
-	}
+        ServerFtpStatistics stats = ((ServerFtpStatistics) context.getFtpStatistics());
+        if (stats != null) {
+            stats.setLogout(this);
+            LoggerFactory.getLogger(this.getClass()).debug("Statistics login decreased due to user logout");
+        } else {
+            LoggerFactory.getLogger(this.getClass()).warn("Statistics not available in session, can not decrease login  count");
+        }
     }
 
     public void setFileOffset(long fileOffset) {
-	setAttribute(ATTRIBUTE_FILE_OFFSET, fileOffset);
+        setAttribute(ATTRIBUTE_FILE_OFFSET, fileOffset);
 
     }
 
     public void setRenameFrom(FtpFile renFr) {
-	setAttribute(ATTRIBUTE_RENAME_FROM, renFr);
+        setAttribute(ATTRIBUTE_RENAME_FROM, renFr);
 
     }
 
     public FtpFile getRenameFrom() {
-	return (FtpFile) getAttribute(ATTRIBUTE_RENAME_FROM);
+        return (FtpFile) getAttribute(ATTRIBUTE_RENAME_FROM);
     }
 
     public long getFileOffset() {
-	return (Long) getAttribute(ATTRIBUTE_FILE_OFFSET, 0L);
+        return (Long) getAttribute(ATTRIBUTE_FILE_OFFSET, 0L);
     }
 
     public void setStructure(Structure structure) {
-	setAttribute(ATTRIBUTE_STRUCTURE, structure);
+        setAttribute(ATTRIBUTE_STRUCTURE, structure);
     }
 
     public void setDataType(DataType dataType) {
-	setAttribute(ATTRIBUTE_DATA_TYPE, dataType);
+        setAttribute(ATTRIBUTE_DATA_TYPE, dataType);
 
     }
 
@@ -673,59 +695,59 @@
      * @see FtpSession#getSessionId()
      */
     public UUID getSessionId() {
-	synchronized (wrappedSession) {
-	    if (!wrappedSession.containsAttribute(ATTRIBUTE_SESSION_ID)) {
-		wrappedSession.setAttribute(ATTRIBUTE_SESSION_ID, UUID.randomUUID());
-	    }
-	    return (UUID) wrappedSession.getAttribute(ATTRIBUTE_SESSION_ID);
-	}
+        synchronized (wrappedSession) {
+            if (!wrappedSession.containsAttribute(ATTRIBUTE_SESSION_ID)) {
+                wrappedSession.setAttribute(ATTRIBUTE_SESSION_ID, UUID.randomUUID());
+            }
+            return (UUID) wrappedSession.getAttribute(ATTRIBUTE_SESSION_ID);
+        }
     }
 
     public FtpIoSession(IoSession wrappedSession, FtpServerContext context) {
-	this.wrappedSession = wrappedSession;
-	this.context = context;
+        this.wrappedSession = wrappedSession;
+        this.context = context;
     }
 
     public Structure getStructure() {
-	return (Structure) getAttribute(ATTRIBUTE_STRUCTURE, Structure.FILE);
+        return (Structure) getAttribute(ATTRIBUTE_STRUCTURE, Structure.FILE);
     }
 
     public DataType getDataType() {
-	return (DataType) getAttribute(ATTRIBUTE_DATA_TYPE, DataType.ASCII);
+        return (DataType) getAttribute(ATTRIBUTE_DATA_TYPE, DataType.ASCII);
     }
 
     public Date getLoginTime() {
-	return (Date) getAttribute(ATTRIBUTE_LOGIN_TIME);
+        return (Date) getAttribute(ATTRIBUTE_LOGIN_TIME);
     }
 
     public Date getLastAccessTime() {
-	return (Date) getAttribute(ATTRIBUTE_LAST_ACCESS_TIME);
+        return (Date) getAttribute(ATTRIBUTE_LAST_ACCESS_TIME);
     }
 
     public Certificate[] getClientCertificates() {
-	if (getFilterChain().contains(SslFilter.class)) {
-	    SslFilter sslFilter = (SslFilter) getFilterChain().get(
-		    SslFilter.class);
+        if (getFilterChain().contains(SslFilter.class)) {
+            SslFilter sslFilter = (SslFilter) getFilterChain().get(
+                    SslFilter.class);
 
-	    SSLSession sslSession = sslFilter.getSslSession(this);
+            SSLSession sslSession = sslFilter.getSslSession(this);
 
-	    if (sslSession != null) {
-		try {
-		    return sslSession.getPeerCertificates();
-		} catch (SSLPeerUnverifiedException e) {
-		    // ignore, certificate will not be available to the session
-		}
-	    }
+            if (sslSession != null) {
+                try {
+                    return sslSession.getPeerCertificates();
+                } catch (SSLPeerUnverifiedException e) {
+                    // ignore, certificate will not be available to the session
+                }
+            }
 
-	}
+        }
 
-	// no certificates available
-	return null;
+        // no certificates available
+        return null;
 
     }
 
     public void updateLastAccessTime() {
-	setAttribute(ATTRIBUTE_LAST_ACCESS_TIME, new Date());
+        setAttribute(ATTRIBUTE_LAST_ACCESS_TIME, new Date());
 
     }
 
@@ -733,35 +755,35 @@
      * @see IoSession#getCurrentWriteMessage()
      */
     public Object getCurrentWriteMessage() {
-	return wrappedSession.getCurrentWriteMessage();
+        return wrappedSession.getCurrentWriteMessage();
     }
 
     /**
      * @see IoSession#getCurrentWriteRequest()
      */
     public WriteRequest getCurrentWriteRequest() {
-	return wrappedSession.getCurrentWriteRequest();
+        return wrappedSession.getCurrentWriteRequest();
     }
 
     /**
      * @see IoSession#isBothIdle()
      */
     public boolean isBothIdle() {
-	return wrappedSession.isBothIdle();
+        return wrappedSession.isBothIdle();
     }
 
     /**
      * @see IoSession#isReaderIdle()
      */
     public boolean isReaderIdle() {
-	return wrappedSession.isReaderIdle();
+        return wrappedSession.isReaderIdle();
     }
 
     /**
      * @see IoSession#isWriterIdle()
      */
     public boolean isWriterIdle() {
-	return wrappedSession.isWriterIdle();
+        return wrappedSession.isWriterIdle();
     }
 
     /**
@@ -771,7 +793,7 @@
      * @return true if the control socket is secured
      */
     public boolean isSecure() {
-	return getFilterChain().contains(SslFilter.class);
+        return getFilterChain().contains(SslFilter.class);
     }
 
     /**
@@ -779,11 +801,11 @@
      * @param increment The number of bytes written
      */
     public void increaseWrittenDataBytes(int increment) {
-	if (wrappedSession instanceof AbstractIoSession) {
-	    ((AbstractIoSession) wrappedSession).increaseScheduledWriteBytes(increment);
-	    ((AbstractIoSession) wrappedSession).increaseWrittenBytes(
-		    increment, System.currentTimeMillis());
-	}
+        if (wrappedSession instanceof AbstractIoSession) {
+            ((AbstractIoSession) wrappedSession).increaseScheduledWriteBytes(increment);
+            ((AbstractIoSession) wrappedSession).increaseWrittenBytes(
+                    increment, System.currentTimeMillis());
+        }
     }
 
     /**
@@ -791,10 +813,10 @@
      * @param increment The number of bytes written
      */
     public void increaseReadDataBytes(int increment) {
-	if (wrappedSession instanceof AbstractIoSession) {
-	    ((AbstractIoSession) wrappedSession).increaseReadBytes(increment,
-		    System.currentTimeMillis());
-	}
+        if (wrappedSession instanceof AbstractIoSession) {
+            ((AbstractIoSession) wrappedSession).increaseReadBytes(increment,
+                    System.currentTimeMillis());
+        }
     }
 
     /**
@@ -802,41 +824,45 @@
      * @return the last reply that was sent to the client.
      */
     public FtpReply getLastReply() {
-	return lastReply;
+        return lastReply;
     }
 
     /**
      * @see IoSession#getWriteRequestQueue()
      */
     public WriteRequestQueue getWriteRequestQueue() {
-	return wrappedSession.getWriteRequestQueue();
+        return wrappedSession.getWriteRequestQueue();
     }
 
     /**
      * @see IoSession#isReadSuspended()
      */
     public boolean isReadSuspended() {
-	return wrappedSession.isReadSuspended();
+        return wrappedSession.isReadSuspended();
     }
 
     /**
      * @see IoSession#isWriteSuspended()
      */
     public boolean isWriteSuspended() {
-	return wrappedSession.isWriteSuspended();
+        return wrappedSession.isWriteSuspended();
     }
 
     /**
      * @see IoSession#setCurrentWriteRequest(WriteRequest)
      */
     public void setCurrentWriteRequest(WriteRequest currentWriteRequest) {
-	wrappedSession.setCurrentWriteRequest(currentWriteRequest);
+        wrappedSession.setCurrentWriteRequest(currentWriteRequest);
     }
 
     /**
      * @see IoSession#updateThroughput(long, boolean)
      */
     public void updateThroughput(long currentTime, boolean force) {
-	wrappedSession.updateThroughput(currentTime, force);
+        wrappedSession.updateThroughput(currentTime, force);
+    }
+
+    public boolean isSecured() {
+        return getFilterChain().contains(SslFilter.class);
     }
 }
diff --git a/core/src/main/java/org/apache/ftpserver/listener/nio/FtpHandlerAdapter.java b/core/src/main/java/org/apache/ftpserver/listener/nio/FtpHandlerAdapter.java
index 28452b5..cb38cd6 100644
--- a/core/src/main/java/org/apache/ftpserver/listener/nio/FtpHandlerAdapter.java
+++ b/core/src/main/java/org/apache/ftpserver/listener/nio/FtpHandlerAdapter.java
@@ -6,16 +6,16 @@
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
- *  
+ * 
  *    http://www.apache.org/licenses/LICENSE-2.0
- *  
+ * 
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
- *  under the License. 
- *  
+ *  under the License.
+ * 
  */
 package org.apache.ftpserver.listener.nio;
 
@@ -25,7 +25,7 @@
 import org.apache.ftpserver.impl.FtpHandler;
 import org.apache.ftpserver.impl.FtpIoSession;
 import org.apache.ftpserver.impl.FtpServerContext;
-import org.apache.mina.core.service.IoHandler;
+import org.apache.mina.core.service.IoHandlerAdapter;
 import org.apache.mina.core.session.IdleStatus;
 import org.apache.mina.core.session.IoSession;
 import org.apache.mina.filter.logging.MdcInjectionFilter;
@@ -38,7 +38,7 @@
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  *
  */
-public class FtpHandlerAdapter implements IoHandler {
+public class FtpHandlerAdapter extends IoHandlerAdapter {
     private final FtpServerContext context;
 
     private FtpHandler ftpHandler;
@@ -77,7 +77,7 @@
         MdcInjectionFilter.setProperty(session, "session", ftpSession.getSessionId().toString());
 
         ftpHandler.sessionCreated(ftpSession);
-        
+
     }
 
     public void sessionIdle(IoSession session, IdleStatus status)
diff --git a/core/src/test/java/org/apache/ftpserver/clienttests/FtpMd5Test.java b/core/src/test/java/org/apache/ftpserver/clienttests/FtpMd5Test.java
index ccaa47d..5349f69 100644
--- a/core/src/test/java/org/apache/ftpserver/clienttests/FtpMd5Test.java
+++ b/core/src/test/java/org/apache/ftpserver/clienttests/FtpMd5Test.java
@@ -20,6 +20,7 @@
 package org.apache.ftpserver.clienttests;
 
 import java.io.File;
+import java.security.Security;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -50,6 +51,12 @@
 
     private static String testData2Hash;
 
+    // Enabling SSLv3 because Java 8 disable it by default...
+    static
+    {
+        Security.setProperty( "jdk.tls.disabledAlgorithms", "RC4, MD5withRSA, DH keySize < 768" );
+    }
+
     /*
      * (non-Javadoc)
      * 
diff --git a/core/src/test/java/org/apache/ftpserver/impl/DefaultFtpServerTest.java b/core/src/test/java/org/apache/ftpserver/impl/DefaultFtpServerTest.java
index d6a2ab5..f560fb1 100644
--- a/core/src/test/java/org/apache/ftpserver/impl/DefaultFtpServerTest.java
+++ b/core/src/test/java/org/apache/ftpserver/impl/DefaultFtpServerTest.java
@@ -74,4 +74,40 @@
         }
     }
     
+    public void testStartFtpServer() throws Exception {
+        // FTPSERVER-197
+        
+        FtpServerFactory serverFactory = new FtpServerFactory();
+        
+        ListenerFactory listenerFactory = new ListenerFactory();
+        listenerFactory.setPort(0);
+        
+        // let's create two listeners on the same port, second should not start
+     
+        Listener defaultListener = listenerFactory.createListener();
+        Listener secondListener = listenerFactory.createListener();
+        
+        
+        serverFactory.addListener("default", defaultListener);
+        
+        FtpServer server = serverFactory.createServer();
+        
+        try {
+            server.start();
+            
+            // Windows seems to allow for both listeners to bind on the same port...
+            //fail("Must throw FtpServerConfigurationException");
+        } catch(FtpServerConfigurationException e) {
+            if(e.getCause() instanceof BindException) {
+                // OK!
+                
+                // we failed to start, make sure things are shut down correctly
+                assertTrue(defaultListener.isStopped());
+                assertTrue(secondListener.isStopped());
+                assertTrue(server.isStopped());
+            } else {
+                throw e;
+            }
+        }
+    }
 }
diff --git a/core/src/test/java/org/apache/ftpserver/ssl/ExplicitSecurityTestTemplate.java b/core/src/test/java/org/apache/ftpserver/ssl/ExplicitSecurityTestTemplate.java
index 69b0df0..053d0ee 100644
--- a/core/src/test/java/org/apache/ftpserver/ssl/ExplicitSecurityTestTemplate.java
+++ b/core/src/test/java/org/apache/ftpserver/ssl/ExplicitSecurityTestTemplate.java
@@ -22,6 +22,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.InputStream;
+import java.security.Security;
 
 import org.apache.commons.net.ftp.FTPReply;
 import org.apache.commons.net.ftp.FTPSClient;
@@ -39,6 +40,12 @@
     protected static final File TEST_FILE2 = new File(ROOT_DIR, "test2.txt");
 
     protected static final byte[] TEST_DATA = "TESTDATA".getBytes();
+    
+    // Enabling SSLv3 because Java 8 disable it by default...
+    static
+    {
+        Security.setProperty( "jdk.tls.disabledAlgorithms", "RC4, MD5withRSA, DH keySize < 768" );
+    }
 
     @Override
     protected void setUp() throws Exception {
diff --git a/core/src/test/java/org/apache/ftpserver/ssl/MinaExplicitSSLTest.java b/core/src/test/java/org/apache/ftpserver/ssl/MinaExplicitSSLTest.java
index ece983f..109571f 100644
--- a/core/src/test/java/org/apache/ftpserver/ssl/MinaExplicitSSLTest.java
+++ b/core/src/test/java/org/apache/ftpserver/ssl/MinaExplicitSSLTest.java
@@ -30,5 +30,4 @@
     protected String getAuthValue() {
         return "SSL";
     }
-
 }
diff --git a/core/src/test/java/org/apache/ftpserver/ssl/MinaExplicitTLSTest.java b/core/src/test/java/org/apache/ftpserver/ssl/MinaExplicitTLSTest.java
index d1d4161..fdcc05d 100644
--- a/core/src/test/java/org/apache/ftpserver/ssl/MinaExplicitTLSTest.java
+++ b/core/src/test/java/org/apache/ftpserver/ssl/MinaExplicitTLSTest.java
@@ -30,5 +30,4 @@
     protected String getAuthValue() {
         return "TLS";
     }
-
 }