Fix eol-style

git-svn-id: https://svn.apache.org/repos/asf/mina/ftpserver/trunk@1129826 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/main/java/org/apache/ftpserver/impl/FtpReplyTranslator.java b/core/src/main/java/org/apache/ftpserver/impl/FtpReplyTranslator.java
index 156330c..15a74e2 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/FtpReplyTranslator.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/FtpReplyTranslator.java
@@ -1,504 +1,504 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * 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.

- */

-

-package org.apache.ftpserver.impl;

-

-import java.net.InetAddress;

-import java.net.InetSocketAddress;

-import java.net.SocketAddress;

-

-import org.apache.ftpserver.ftplet.FileSystemView;

-import org.apache.ftpserver.ftplet.FtpRequest;

-import org.apache.ftpserver.ftplet.FtpStatistics;

-import org.apache.ftpserver.message.MessageResource;

-import org.apache.ftpserver.util.DateUtils;

-

-/**

- * A utility class for returning translated messages. The utility method,

- * <code>translateMessage</code> also expands any variables in the message.

- * 

- * @author <a href="http://mina.apache.org">Apache MINA Project</a>

- * 

- */

-

-public class FtpReplyTranslator {

-

-	public static final String CLIENT_ACCESS_TIME = "client.access.time";

-

-	public static final String CLIENT_CON_TIME = "client.con.time";

-

-	public static final String CLIENT_DIR = "client.dir";

-

-	public static final String CLIENT_HOME = "client.home";

-

-	public static final String CLIENT_IP = "client.ip";

-

-	public static final String CLIENT_LOGIN_NAME = "client.login.name";

-

-	public static final String CLIENT_LOGIN_TIME = "client.login.time";

-

-	public static final String OUTPUT_CODE = "output.code";

-

-	public static final String OUTPUT_MSG = "output.msg";

-

-	public static final String REQUEST_ARG = "request.arg";

-

-	public static final String REQUEST_CMD = "request.cmd";

-

-	public static final String REQUEST_LINE = "request.line";

-

-	// /////////////////////// All Server Vatiables /////////////////////////

-	public static final String SERVER_IP = "server.ip";

-

-	public static final String SERVER_PORT = "server.port";

-

-	public static final String STAT_CON_CURR = "stat.con.curr";

-

-	public static final String STAT_CON_TOTAL = "stat.con.total";

-

-	public static final String STAT_DIR_CREATE_COUNT = "stat.dir.create.count";

-

-	public static final String STAT_DIR_DELETE_COUNT = "stat.dir.delete.count";

-

-	public static final String STAT_FILE_DELETE_COUNT = "stat.file.delete.count";

-

-	public static final String STAT_FILE_DOWNLOAD_BYTES = "stat.file.download.bytes";

-

-	public static final String STAT_FILE_DOWNLOAD_COUNT = "stat.file.download.count";

-

-	public static final String STAT_FILE_UPLOAD_BYTES = "stat.file.upload.bytes";

-

-	public static final String STAT_FILE_UPLOAD_COUNT = "stat.file.upload.count";

-

-	public static final String STAT_LOGIN_ANON_CURR = "stat.login.anon.curr";

-

-	public static final String STAT_LOGIN_ANON_TOTAL = "stat.login.anon.total";

-

-	public static final String STAT_LOGIN_CURR = "stat.login.curr";

-

-	public static final String STAT_LOGIN_TOTAL = "stat.login.total";

-

-	public static final String STAT_START_TIME = "stat.start.time";

-

-	/**

-	 * Returns the translated message.

-	 * 

-	 * @param session

-	 *            the FTP session for which a reply is to be sent

-	 * @param request

-	 *            the FTP request object

-	 * @param context

-	 *            the FTP server context

-	 * @param code

-	 *            the reply code

-	 * @param subId

-	 *            the ID of the sub message

-	 * @param basicMsg

-	 *            the basic message

-	 * @return the translated message

-	 */

-	public static String translateMessage(FtpIoSession session,

-		FtpRequest request, FtpServerContext context, int code, String subId,

-		String basicMsg) {

-		MessageResource resource = context.getMessageResource();

-		String lang = session.getLanguage();

-

-		String msg = null;

-		if (resource != null) {

-			msg = resource.getMessage(code, subId, lang);

-		}

-		if (msg == null) {

-			msg = "";

-		}

-		msg = replaceVariables(session, request, context, code, basicMsg, msg);

-

-		return msg;

-	}

-

-	/**

-	 * Replace server variables.

-	 */

-	private static String replaceVariables(FtpIoSession session,

-		FtpRequest request, FtpServerContext context, int code,

-		String basicMsg, String str) {

-

-		int startIndex = 0;

-		int openIndex = str.indexOf('{', startIndex);

-		if (openIndex == -1) {

-			return str;

-		}

-

-		int closeIndex = str.indexOf('}', startIndex);

-		if ((closeIndex == -1) || (openIndex > closeIndex)) {

-			return str;

-		}

-

-		StringBuilder sb = new StringBuilder(128);

-		sb.append(str.substring(startIndex, openIndex));

-		while (true) {

-			String varName = str.substring(openIndex + 1, closeIndex);

-			sb.append(getVariableValue(session, request, context, code,

-				basicMsg, varName));

-

-			startIndex = closeIndex + 1;

-			openIndex = str.indexOf('{', startIndex);

-			if (openIndex == -1) {

-				sb.append(str.substring(startIndex));

-				break;

-			}

-

-			closeIndex = str.indexOf('}', startIndex);

-			if ((closeIndex == -1) || (openIndex > closeIndex)) {

-				sb.append(str.substring(startIndex));

-				break;

-			}

-			sb.append(str.substring(startIndex, openIndex));

-		}

-		return sb.toString();

-	}

-

-	/**

-	 * Get the variable value.

-	 */

-	private static String getVariableValue(FtpIoSession session,

-		FtpRequest request, FtpServerContext context, int code,

-		String basicMsg, String varName) {

-

-		String varVal = null;

-

-		// all output variables

-		if (varName.startsWith("output.")) {

-			varVal = getOutputVariableValue(session, code, basicMsg, varName);

-		}

-

-		// all server variables

-		else if (varName.startsWith("server.")) {

-			varVal = getServerVariableValue(session, varName);

-		}

-

-		// all request variables

-		else if (varName.startsWith("request.")) {

-			varVal = getRequestVariableValue(session, request, varName);

-		}

-

-		// all statistical variables

-		else if (varName.startsWith("stat.")) {

-			varVal = getStatisticalVariableValue(session, context, varName);

-		}

-

-		// all client variables

-		else if (varName.startsWith("client.")) {

-			varVal = getClientVariableValue(session, varName);

-		}

-

-		if (varVal == null) {

-			varVal = "";

-		}

-		return varVal;

-	}

-

-	/**

-	 * Get client variable value.

-	 */

-	private static String getClientVariableValue(FtpIoSession session,

-		String varName) {

-

-		String varVal = null;

-

-		// client ip

-		if (varName.equals(CLIENT_IP)) {

-			if (session.getRemoteAddress() instanceof InetSocketAddress) {

-				InetSocketAddress remoteSocketAddress = (InetSocketAddress) session.getRemoteAddress();

-				varVal = remoteSocketAddress.getAddress().getHostAddress();

-			}

-

-		}

-

-		// client connection time

-		else if (varName.equals(CLIENT_CON_TIME)) {

-			varVal = DateUtils.getISO8601Date(session.getCreationTime());

-		}

-

-		// client login name

-		else if (varName.equals(CLIENT_LOGIN_NAME)) {

-			if (session.getUser() != null) {

-				varVal = session.getUser().getName();

-			}

-		}

-

-		// client login time

-		else if (varName.equals(CLIENT_LOGIN_TIME)) {

-			varVal = DateUtils.getISO8601Date(session.getLoginTime().getTime());

-		}

-

-		// client last access time

-		else if (varName.equals(CLIENT_ACCESS_TIME)) {

-			varVal = DateUtils.getISO8601Date(session.getLastAccessTime().getTime());

-		}

-

-		// client home

-		else if (varName.equals(CLIENT_HOME)) {

-			varVal = session.getUser().getHomeDirectory();

-		}

-

-		// client directory

-		else if (varName.equals(CLIENT_DIR)) {

-			FileSystemView fsView = session.getFileSystemView();

-			if (fsView != null) {

-				try {

-					varVal = fsView.getWorkingDirectory().getAbsolutePath();

-				}

-				catch (Exception ex) {

-					varVal = "";

-				}

-			}

-		}

-		return varVal;

-	}

-

-	/**

-	 * Get output variable value.

-	 */

-	private static String getOutputVariableValue(FtpIoSession session,

-		int code, String basicMsg, String varName) {

-		String varVal = null;

-

-		// output code

-		if (varName.equals(OUTPUT_CODE)) {

-			varVal = String.valueOf(code);

-		}

-

-		// output message

-		else if (varName.equals(OUTPUT_MSG)) {

-			varVal = basicMsg;

-		}

-

-		return varVal;

-	}

-

-	/**

-	 * Get request variable value.

-	 */

-	private static String getRequestVariableValue(FtpIoSession session,

-		FtpRequest request, String varName) {

-

-		String varVal = null;

-

-		if (request == null) {

-			return "";

-		}

-

-		// request line

-		if (varName.equals(REQUEST_LINE)) {

-			varVal = request.getRequestLine();

-		}

-

-		// request command

-		else if (varName.equals(REQUEST_CMD)) {

-			varVal = request.getCommand();

-		}

-

-		// request argument

-		else if (varName.equals(REQUEST_ARG)) {

-			varVal = request.getArgument();

-		}

-

-		return varVal;

-	}

-

-	/**

-	 * Get server variable value.

-	 */

-	private static String getServerVariableValue(FtpIoSession session,

-		String varName) {

-

-		String varVal = null;

-

-		SocketAddress localSocketAddress = session.getLocalAddress();

-

-		if (localSocketAddress instanceof InetSocketAddress) {

-			InetSocketAddress localInetSocketAddress = (InetSocketAddress) localSocketAddress;

-			// server address

-			if (varName.equals(SERVER_IP)) {

-

-				InetAddress addr = localInetSocketAddress.getAddress();

-

-				if (addr != null) {

-					varVal = addr.getHostAddress();

-				}

-			}

-

-			// server port

-			else if (varName.equals(SERVER_PORT)) {

-				varVal = String.valueOf(localInetSocketAddress.getPort());

-			}

-		}

-

-		return varVal;

-	}

-

-	/**

-	 * Get statistical connection variable value.

-	 */

-	private static String getStatisticalConnectionVariableValue(

-		FtpIoSession session, FtpServerContext context, String varName) {

-		String varVal = null;

-		FtpStatistics stat = context.getFtpStatistics();

-

-		// total connection number

-		if (varName.equals(STAT_CON_TOTAL)) {

-			varVal = String.valueOf(stat.getTotalConnectionNumber());

-		}

-

-		// current connection number

-		else if (varName.equals(STAT_CON_CURR)) {

-			varVal = String.valueOf(stat.getCurrentConnectionNumber());

-		}

-

-		return varVal;

-	}

-

-	/**

-	 * Get statistical directory variable value.

-	 */

-	private static String getStatisticalDirectoryVariableValue(

-		FtpIoSession session, FtpServerContext context, String varName) {

-		String varVal = null;

-		FtpStatistics stat = context.getFtpStatistics();

-

-		// total directory created

-		if (varName.equals(STAT_DIR_CREATE_COUNT)) {

-			varVal = String.valueOf(stat.getTotalDirectoryCreated());

-		}

-

-		// total directory removed

-		else if (varName.equals(STAT_DIR_DELETE_COUNT)) {

-			varVal = String.valueOf(stat.getTotalDirectoryRemoved());

-		}

-

-		return varVal;

-	}

-

-	/**

-	 * Get statistical file variable value.

-	 */

-	private static String getStatisticalFileVariableValue(FtpIoSession session,

-		FtpServerContext context, String varName) {

-		String varVal = null;

-		FtpStatistics stat = context.getFtpStatistics();

-

-		// total number of file upload

-		if (varName.equals(STAT_FILE_UPLOAD_COUNT)) {

-			varVal = String.valueOf(stat.getTotalUploadNumber());

-		}

-

-		// total bytes uploaded

-		else if (varName.equals(STAT_FILE_UPLOAD_BYTES)) {

-			varVal = String.valueOf(stat.getTotalUploadSize());

-		}

-

-		// total number of file download

-		else if (varName.equals(STAT_FILE_DOWNLOAD_COUNT)) {

-			varVal = String.valueOf(stat.getTotalDownloadNumber());

-		}

-

-		// total bytes downloaded

-		else if (varName.equals(STAT_FILE_DOWNLOAD_BYTES)) {

-			varVal = String.valueOf(stat.getTotalDownloadSize());

-		}

-

-		// total number of files deleted

-		else if (varName.equals(STAT_FILE_DELETE_COUNT)) {

-			varVal = String.valueOf(stat.getTotalDeleteNumber());

-		}

-

-		return varVal;

-	}

-

-	/**

-	 * Get statistical login variable value.

-	 */

-	private static String getStatisticalLoginVariableValue(

-		FtpIoSession session, FtpServerContext context, String varName) {

-		String varVal = null;

-		FtpStatistics stat = context.getFtpStatistics();

-

-		// total login number

-		if (varName.equals(STAT_LOGIN_TOTAL)) {

-			varVal = String.valueOf(stat.getTotalLoginNumber());

-		}

-

-		// current login number

-		else if (varName.equals(STAT_LOGIN_CURR)) {

-			varVal = String.valueOf(stat.getCurrentLoginNumber());

-		}

-

-		// total anonymous login number

-		else if (varName.equals(STAT_LOGIN_ANON_TOTAL)) {

-			varVal = String.valueOf(stat.getTotalAnonymousLoginNumber());

-		}

-

-		// current anonymous login number

-		else if (varName.equals(STAT_LOGIN_ANON_CURR)) {

-			varVal = String.valueOf(stat.getCurrentAnonymousLoginNumber());

-		}

-

-		return varVal;

-	}

-

-	/**

-	 * Get statistical variable value.

-	 */

-	private static String getStatisticalVariableValue(FtpIoSession session,

-		FtpServerContext context, String varName) {

-

-		String varVal = null;

-		FtpStatistics stat = context.getFtpStatistics();

-

-		// server start time

-		if (varName.equals(STAT_START_TIME)) {

-			varVal = DateUtils.getISO8601Date(stat.getStartTime().getTime());

-		}

-

-		// connection statistical variables

-		else if (varName.startsWith("stat.con")) {

-			varVal = getStatisticalConnectionVariableValue(session, context,

-				varName);

-		}

-

-		// login statistical variables

-		else if (varName.startsWith("stat.login.")) {

-			varVal = getStatisticalLoginVariableValue(session, context, varName);

-		}

-

-		// file statistical variable

-		else if (varName.startsWith("stat.file")) {

-			varVal = getStatisticalFileVariableValue(session, context, varName);

-		}

-

-		// directory statistical variable

-		else if (varName.startsWith("stat.dir.")) {

-			varVal = getStatisticalDirectoryVariableValue(session, context,

-				varName);

-		}

-

-		return varVal;

-	}

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * 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.
+ */
+
+package org.apache.ftpserver.impl;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+
+import org.apache.ftpserver.ftplet.FileSystemView;
+import org.apache.ftpserver.ftplet.FtpRequest;
+import org.apache.ftpserver.ftplet.FtpStatistics;
+import org.apache.ftpserver.message.MessageResource;
+import org.apache.ftpserver.util.DateUtils;
+
+/**
+ * A utility class for returning translated messages. The utility method,
+ * <code>translateMessage</code> also expands any variables in the message.
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+
+public class FtpReplyTranslator {
+
+	public static final String CLIENT_ACCESS_TIME = "client.access.time";
+
+	public static final String CLIENT_CON_TIME = "client.con.time";
+
+	public static final String CLIENT_DIR = "client.dir";
+
+	public static final String CLIENT_HOME = "client.home";
+
+	public static final String CLIENT_IP = "client.ip";
+
+	public static final String CLIENT_LOGIN_NAME = "client.login.name";
+
+	public static final String CLIENT_LOGIN_TIME = "client.login.time";
+
+	public static final String OUTPUT_CODE = "output.code";
+
+	public static final String OUTPUT_MSG = "output.msg";
+
+	public static final String REQUEST_ARG = "request.arg";
+
+	public static final String REQUEST_CMD = "request.cmd";
+
+	public static final String REQUEST_LINE = "request.line";
+
+	// /////////////////////// All Server Vatiables /////////////////////////
+	public static final String SERVER_IP = "server.ip";
+
+	public static final String SERVER_PORT = "server.port";
+
+	public static final String STAT_CON_CURR = "stat.con.curr";
+
+	public static final String STAT_CON_TOTAL = "stat.con.total";
+
+	public static final String STAT_DIR_CREATE_COUNT = "stat.dir.create.count";
+
+	public static final String STAT_DIR_DELETE_COUNT = "stat.dir.delete.count";
+
+	public static final String STAT_FILE_DELETE_COUNT = "stat.file.delete.count";
+
+	public static final String STAT_FILE_DOWNLOAD_BYTES = "stat.file.download.bytes";
+
+	public static final String STAT_FILE_DOWNLOAD_COUNT = "stat.file.download.count";
+
+	public static final String STAT_FILE_UPLOAD_BYTES = "stat.file.upload.bytes";
+
+	public static final String STAT_FILE_UPLOAD_COUNT = "stat.file.upload.count";
+
+	public static final String STAT_LOGIN_ANON_CURR = "stat.login.anon.curr";
+
+	public static final String STAT_LOGIN_ANON_TOTAL = "stat.login.anon.total";
+
+	public static final String STAT_LOGIN_CURR = "stat.login.curr";
+
+	public static final String STAT_LOGIN_TOTAL = "stat.login.total";
+
+	public static final String STAT_START_TIME = "stat.start.time";
+
+	/**
+	 * Returns the translated message.
+	 * 
+	 * @param session
+	 *            the FTP session for which a reply is to be sent
+	 * @param request
+	 *            the FTP request object
+	 * @param context
+	 *            the FTP server context
+	 * @param code
+	 *            the reply code
+	 * @param subId
+	 *            the ID of the sub message
+	 * @param basicMsg
+	 *            the basic message
+	 * @return the translated message
+	 */
+	public static String translateMessage(FtpIoSession session,
+		FtpRequest request, FtpServerContext context, int code, String subId,
+		String basicMsg) {
+		MessageResource resource = context.getMessageResource();
+		String lang = session.getLanguage();
+
+		String msg = null;
+		if (resource != null) {
+			msg = resource.getMessage(code, subId, lang);
+		}
+		if (msg == null) {
+			msg = "";
+		}
+		msg = replaceVariables(session, request, context, code, basicMsg, msg);
+
+		return msg;
+	}
+
+	/**
+	 * Replace server variables.
+	 */
+	private static String replaceVariables(FtpIoSession session,
+		FtpRequest request, FtpServerContext context, int code,
+		String basicMsg, String str) {
+
+		int startIndex = 0;
+		int openIndex = str.indexOf('{', startIndex);
+		if (openIndex == -1) {
+			return str;
+		}
+
+		int closeIndex = str.indexOf('}', startIndex);
+		if ((closeIndex == -1) || (openIndex > closeIndex)) {
+			return str;
+		}
+
+		StringBuilder sb = new StringBuilder(128);
+		sb.append(str.substring(startIndex, openIndex));
+		while (true) {
+			String varName = str.substring(openIndex + 1, closeIndex);
+			sb.append(getVariableValue(session, request, context, code,
+				basicMsg, varName));
+
+			startIndex = closeIndex + 1;
+			openIndex = str.indexOf('{', startIndex);
+			if (openIndex == -1) {
+				sb.append(str.substring(startIndex));
+				break;
+			}
+
+			closeIndex = str.indexOf('}', startIndex);
+			if ((closeIndex == -1) || (openIndex > closeIndex)) {
+				sb.append(str.substring(startIndex));
+				break;
+			}
+			sb.append(str.substring(startIndex, openIndex));
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Get the variable value.
+	 */
+	private static String getVariableValue(FtpIoSession session,
+		FtpRequest request, FtpServerContext context, int code,
+		String basicMsg, String varName) {
+
+		String varVal = null;
+
+		// all output variables
+		if (varName.startsWith("output.")) {
+			varVal = getOutputVariableValue(session, code, basicMsg, varName);
+		}
+
+		// all server variables
+		else if (varName.startsWith("server.")) {
+			varVal = getServerVariableValue(session, varName);
+		}
+
+		// all request variables
+		else if (varName.startsWith("request.")) {
+			varVal = getRequestVariableValue(session, request, varName);
+		}
+
+		// all statistical variables
+		else if (varName.startsWith("stat.")) {
+			varVal = getStatisticalVariableValue(session, context, varName);
+		}
+
+		// all client variables
+		else if (varName.startsWith("client.")) {
+			varVal = getClientVariableValue(session, varName);
+		}
+
+		if (varVal == null) {
+			varVal = "";
+		}
+		return varVal;
+	}
+
+	/**
+	 * Get client variable value.
+	 */
+	private static String getClientVariableValue(FtpIoSession session,
+		String varName) {
+
+		String varVal = null;
+
+		// client ip
+		if (varName.equals(CLIENT_IP)) {
+			if (session.getRemoteAddress() instanceof InetSocketAddress) {
+				InetSocketAddress remoteSocketAddress = (InetSocketAddress) session.getRemoteAddress();
+				varVal = remoteSocketAddress.getAddress().getHostAddress();
+			}
+
+		}
+
+		// client connection time
+		else if (varName.equals(CLIENT_CON_TIME)) {
+			varVal = DateUtils.getISO8601Date(session.getCreationTime());
+		}
+
+		// client login name
+		else if (varName.equals(CLIENT_LOGIN_NAME)) {
+			if (session.getUser() != null) {
+				varVal = session.getUser().getName();
+			}
+		}
+
+		// client login time
+		else if (varName.equals(CLIENT_LOGIN_TIME)) {
+			varVal = DateUtils.getISO8601Date(session.getLoginTime().getTime());
+		}
+
+		// client last access time
+		else if (varName.equals(CLIENT_ACCESS_TIME)) {
+			varVal = DateUtils.getISO8601Date(session.getLastAccessTime().getTime());
+		}
+
+		// client home
+		else if (varName.equals(CLIENT_HOME)) {
+			varVal = session.getUser().getHomeDirectory();
+		}
+
+		// client directory
+		else if (varName.equals(CLIENT_DIR)) {
+			FileSystemView fsView = session.getFileSystemView();
+			if (fsView != null) {
+				try {
+					varVal = fsView.getWorkingDirectory().getAbsolutePath();
+				}
+				catch (Exception ex) {
+					varVal = "";
+				}
+			}
+		}
+		return varVal;
+	}
+
+	/**
+	 * Get output variable value.
+	 */
+	private static String getOutputVariableValue(FtpIoSession session,
+		int code, String basicMsg, String varName) {
+		String varVal = null;
+
+		// output code
+		if (varName.equals(OUTPUT_CODE)) {
+			varVal = String.valueOf(code);
+		}
+
+		// output message
+		else if (varName.equals(OUTPUT_MSG)) {
+			varVal = basicMsg;
+		}
+
+		return varVal;
+	}
+
+	/**
+	 * Get request variable value.
+	 */
+	private static String getRequestVariableValue(FtpIoSession session,
+		FtpRequest request, String varName) {
+
+		String varVal = null;
+
+		if (request == null) {
+			return "";
+		}
+
+		// request line
+		if (varName.equals(REQUEST_LINE)) {
+			varVal = request.getRequestLine();
+		}
+
+		// request command
+		else if (varName.equals(REQUEST_CMD)) {
+			varVal = request.getCommand();
+		}
+
+		// request argument
+		else if (varName.equals(REQUEST_ARG)) {
+			varVal = request.getArgument();
+		}
+
+		return varVal;
+	}
+
+	/**
+	 * Get server variable value.
+	 */
+	private static String getServerVariableValue(FtpIoSession session,
+		String varName) {
+
+		String varVal = null;
+
+		SocketAddress localSocketAddress = session.getLocalAddress();
+
+		if (localSocketAddress instanceof InetSocketAddress) {
+			InetSocketAddress localInetSocketAddress = (InetSocketAddress) localSocketAddress;
+			// server address
+			if (varName.equals(SERVER_IP)) {
+
+				InetAddress addr = localInetSocketAddress.getAddress();
+
+				if (addr != null) {
+					varVal = addr.getHostAddress();
+				}
+			}
+
+			// server port
+			else if (varName.equals(SERVER_PORT)) {
+				varVal = String.valueOf(localInetSocketAddress.getPort());
+			}
+		}
+
+		return varVal;
+	}
+
+	/**
+	 * Get statistical connection variable value.
+	 */
+	private static String getStatisticalConnectionVariableValue(
+		FtpIoSession session, FtpServerContext context, String varName) {
+		String varVal = null;
+		FtpStatistics stat = context.getFtpStatistics();
+
+		// total connection number
+		if (varName.equals(STAT_CON_TOTAL)) {
+			varVal = String.valueOf(stat.getTotalConnectionNumber());
+		}
+
+		// current connection number
+		else if (varName.equals(STAT_CON_CURR)) {
+			varVal = String.valueOf(stat.getCurrentConnectionNumber());
+		}
+
+		return varVal;
+	}
+
+	/**
+	 * Get statistical directory variable value.
+	 */
+	private static String getStatisticalDirectoryVariableValue(
+		FtpIoSession session, FtpServerContext context, String varName) {
+		String varVal = null;
+		FtpStatistics stat = context.getFtpStatistics();
+
+		// total directory created
+		if (varName.equals(STAT_DIR_CREATE_COUNT)) {
+			varVal = String.valueOf(stat.getTotalDirectoryCreated());
+		}
+
+		// total directory removed
+		else if (varName.equals(STAT_DIR_DELETE_COUNT)) {
+			varVal = String.valueOf(stat.getTotalDirectoryRemoved());
+		}
+
+		return varVal;
+	}
+
+	/**
+	 * Get statistical file variable value.
+	 */
+	private static String getStatisticalFileVariableValue(FtpIoSession session,
+		FtpServerContext context, String varName) {
+		String varVal = null;
+		FtpStatistics stat = context.getFtpStatistics();
+
+		// total number of file upload
+		if (varName.equals(STAT_FILE_UPLOAD_COUNT)) {
+			varVal = String.valueOf(stat.getTotalUploadNumber());
+		}
+
+		// total bytes uploaded
+		else if (varName.equals(STAT_FILE_UPLOAD_BYTES)) {
+			varVal = String.valueOf(stat.getTotalUploadSize());
+		}
+
+		// total number of file download
+		else if (varName.equals(STAT_FILE_DOWNLOAD_COUNT)) {
+			varVal = String.valueOf(stat.getTotalDownloadNumber());
+		}
+
+		// total bytes downloaded
+		else if (varName.equals(STAT_FILE_DOWNLOAD_BYTES)) {
+			varVal = String.valueOf(stat.getTotalDownloadSize());
+		}
+
+		// total number of files deleted
+		else if (varName.equals(STAT_FILE_DELETE_COUNT)) {
+			varVal = String.valueOf(stat.getTotalDeleteNumber());
+		}
+
+		return varVal;
+	}
+
+	/**
+	 * Get statistical login variable value.
+	 */
+	private static String getStatisticalLoginVariableValue(
+		FtpIoSession session, FtpServerContext context, String varName) {
+		String varVal = null;
+		FtpStatistics stat = context.getFtpStatistics();
+
+		// total login number
+		if (varName.equals(STAT_LOGIN_TOTAL)) {
+			varVal = String.valueOf(stat.getTotalLoginNumber());
+		}
+
+		// current login number
+		else if (varName.equals(STAT_LOGIN_CURR)) {
+			varVal = String.valueOf(stat.getCurrentLoginNumber());
+		}
+
+		// total anonymous login number
+		else if (varName.equals(STAT_LOGIN_ANON_TOTAL)) {
+			varVal = String.valueOf(stat.getTotalAnonymousLoginNumber());
+		}
+
+		// current anonymous login number
+		else if (varName.equals(STAT_LOGIN_ANON_CURR)) {
+			varVal = String.valueOf(stat.getCurrentAnonymousLoginNumber());
+		}
+
+		return varVal;
+	}
+
+	/**
+	 * Get statistical variable value.
+	 */
+	private static String getStatisticalVariableValue(FtpIoSession session,
+		FtpServerContext context, String varName) {
+
+		String varVal = null;
+		FtpStatistics stat = context.getFtpStatistics();
+
+		// server start time
+		if (varName.equals(STAT_START_TIME)) {
+			varVal = DateUtils.getISO8601Date(stat.getStartTime().getTime());
+		}
+
+		// connection statistical variables
+		else if (varName.startsWith("stat.con")) {
+			varVal = getStatisticalConnectionVariableValue(session, context,
+				varName);
+		}
+
+		// login statistical variables
+		else if (varName.startsWith("stat.login.")) {
+			varVal = getStatisticalLoginVariableValue(session, context, varName);
+		}
+
+		// file statistical variable
+		else if (varName.startsWith("stat.file")) {
+			varVal = getStatisticalFileVariableValue(session, context, varName);
+		}
+
+		// directory statistical variable
+		else if (varName.startsWith("stat.dir.")) {
+			varVal = getStatisticalDirectoryVariableValue(session, context,
+				varName);
+		}
+
+		return varVal;
+	}
+
+}
diff --git a/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilterType.java b/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilterType.java
index 9538d2e..569417d 100644
--- a/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilterType.java
+++ b/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilterType.java
@@ -1,58 +1,58 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * 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.

- */

-

-package org.apache.ftpserver.ipfilter;

-

-/**

- * Defines various types of IP Filters.

- * 

- * @author <a href="http://mina.apache.org">Apache MINA Project</a>

- * 

- */

-public enum IpFilterType {

-

-	/**

-	 * filter type that allows a set of predefined IP addresses, also known as a

-	 * white list.

-	 */

-	ALLOW,

-

-	/**

-	 * filter type that blocks a set of predefined IP addresses, also known as a

-	 * black list.

-	 */

-	DENY;

-

-	/**

-	 * Parses the given string into its equivalent enum.

-	 * 

-	 * @param value

-	 *            the string value to parse.

-	 * @return the equivalent enum

-	 */

-	public static IpFilterType parse(String value) {

-		for (IpFilterType type : values()) {

-			if (type.name().equalsIgnoreCase(value)) {

-				return type;

-			}

-		}

-		throw new IllegalArgumentException("Invalid IpFilterType: " + value);

-	}

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * 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.
+ */
+
+package org.apache.ftpserver.ipfilter;
+
+/**
+ * Defines various types of IP Filters.
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public enum IpFilterType {
+
+	/**
+	 * filter type that allows a set of predefined IP addresses, also known as a
+	 * white list.
+	 */
+	ALLOW,
+
+	/**
+	 * filter type that blocks a set of predefined IP addresses, also known as a
+	 * black list.
+	 */
+	DENY;
+
+	/**
+	 * Parses the given string into its equivalent enum.
+	 * 
+	 * @param value
+	 *            the string value to parse.
+	 * @return the equivalent enum
+	 */
+	public static IpFilterType parse(String value) {
+		for (IpFilterType type : values()) {
+			if (type.name().equalsIgnoreCase(value)) {
+				return type;
+			}
+		}
+		throw new IllegalArgumentException("Invalid IpFilterType: " + value);
+	}
+
+}
diff --git a/core/src/main/java/org/apache/ftpserver/ipfilter/SessionFilter.java b/core/src/main/java/org/apache/ftpserver/ipfilter/SessionFilter.java
index ec2b8c5..f85524a 100644
--- a/core/src/main/java/org/apache/ftpserver/ipfilter/SessionFilter.java
+++ b/core/src/main/java/org/apache/ftpserver/ipfilter/SessionFilter.java
@@ -1,43 +1,43 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * 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.

- */

-

-package org.apache.ftpserver.ipfilter;

-

-import org.apache.mina.core.session.IoSession;

-

-/**

- * The interface for filtering sessions based on various session attributes.

- * 

- * @author <a href="http://mina.apache.org">Apache MINA Project</a>

- * 

- */

-

-public interface SessionFilter {

-

-    /**

-     * Tells whether or not the given session is accepted by this filter.

-     * 

-     * @param session

-     *            the session to check

-     * @return <code>true</code>, if the given session is accepted by this

-     *         filter; <code>false</code>, otherwise.

-     */

-    public boolean accept(IoSession session);

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * 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.
+ */
+
+package org.apache.ftpserver.ipfilter;
+
+import org.apache.mina.core.session.IoSession;
+
+/**
+ * The interface for filtering sessions based on various session attributes.
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+
+public interface SessionFilter {
+
+    /**
+     * Tells whether or not the given session is accepted by this filter.
+     * 
+     * @param session
+     *            the session to check
+     * @return <code>true</code>, if the given session is accepted by this
+     *         filter; <code>false</code>, otherwise.
+     */
+    public boolean accept(IoSession session);
+
+}
diff --git a/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java b/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java
index 96168e4..fe9c893 100644
--- a/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java
@@ -1,303 +1,303 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * 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.

- */

-

-package org.apache.ftpserver.listener;

-

-import java.net.InetAddress;

-import java.net.UnknownHostException;

-import java.util.List;

-

-import org.apache.ftpserver.DataConnectionConfiguration;

-import org.apache.ftpserver.DataConnectionConfigurationFactory;

-import org.apache.ftpserver.FtpServerConfigurationException;

-import org.apache.ftpserver.ipfilter.SessionFilter;

-import org.apache.ftpserver.listener.nio.NioListener;

-import org.apache.ftpserver.ssl.SslConfiguration;

-import org.apache.mina.filter.firewall.Subnet;

-

-/**

- * Factory for listeners. Listeners themselves are immutable and must be 

- * created using this factory.

- *

- * @author <a href="http://mina.apache.org">Apache MINA Project</a>

- */

-public class ListenerFactory {

-

-    private String serverAddress;

-

-    private int port = 21;

-

-    private SslConfiguration ssl;

-

-    private boolean implicitSsl = false;

-

-    private DataConnectionConfiguration dataConnectionConfig = new DataConnectionConfigurationFactory()

-            .createDataConnectionConfiguration();

-

-    private int idleTimeout = 300;

-

-    private List<InetAddress> blockedAddresses;

-

-    private List<Subnet> blockedSubnets;

-    

-    /**

-     * The Session filter

-     */

-    private SessionFilter sessionFilter = null;

-

-    /**

-     * Default constructor

-     */

-    public ListenerFactory() {

-        // do nothing

-    }

-

-    /**

-     * Copy constructor, will copy properties from the provided listener.

-     * @param listener The listener which properties will be used for this factory

-     */

-    public ListenerFactory(Listener listener) {

-        serverAddress = listener.getServerAddress();

-        port = listener.getPort();

-        ssl = listener.getSslConfiguration();

-        implicitSsl = listener.isImplicitSsl();

-        dataConnectionConfig = listener.getDataConnectionConfiguration();

-        idleTimeout = listener.getIdleTimeout();

-        // TODO remove the next two lines if and when we remove the deprecated

-        // methods.

-        blockedAddresses = listener.getBlockedAddresses();

-        blockedSubnets = listener.getBlockedSubnets();

-        this.sessionFilter = listener.getSessionFilter();

-    }

-

-    /**

-     * Create a listener based on the settings of this factory. The listener is immutable.

-     * @return The created listener

-     */

-    public Listener createListener() {

-        try {

-            InetAddress.getByName(serverAddress);

-        } catch (UnknownHostException e) {

-            throw new FtpServerConfigurationException("Unknown host", e);

-        }

-        // Deal with the old style black list and new session Filter here.

-        if (sessionFilter != null) {

-            if (blockedAddresses != null || blockedSubnets != null) {

-                throw new IllegalStateException(

-                        "Usage of SessionFilter in combination with blockedAddesses/subnets is not supported. ");

-            }

-        }

-        if (blockedAddresses != null || blockedSubnets != null) {

-            return new NioListener(serverAddress, port, implicitSsl, ssl,

-                    dataConnectionConfig, idleTimeout, blockedAddresses,

-                    blockedSubnets);

-        } else {

-            return new NioListener(serverAddress, port, implicitSsl, ssl,

-                    dataConnectionConfig, idleTimeout, sessionFilter);

-        }

-    }

-

-    /**

-     * Is listeners created by this factory in SSL mode automatically or must the client explicitly

-     * request to use SSL

-     * 

-     * @return true is listeners created by this factory is automatically in SSL mode, false

-     *         otherwise

-     */

-    public boolean isImplicitSsl() {

-        return implicitSsl;

-    }

-

-    /**

-     * Should listeners created by this factory be in SSL mode automatically or must the client

-     * explicitly request to use SSL

-     * 

-     * @param implicitSsl

-     *            true is listeners created by this factory should automatically be in SSL mode,

-     *            false otherwise

-     */

-    public void setImplicitSsl(boolean implicitSsl) {

-        this.implicitSsl = implicitSsl;

-    }

-

-    /**

-     * Get the port on which listeners created by this factory is waiting for requests. 

-     * 

-     * @return The port

-     */

-    public int getPort() {

-        return port;

-    }

-

-    /**

-     * Set the port on which listeners created by this factory will accept requests. Or set to 0

-     * (zero) is the port should be automatically assigned

-     * 

-     * @param port

-     *            The port to use.

-     */

-    public void setPort(int port) {

-        this.port = port;

-    }

-

-    /**

-     * Get the {@link InetAddress} used for binding the local socket. Defaults

-     * to null, that is, the server binds to all available network interfaces

-     * 

-     * @return The local socket {@link InetAddress}, if set

-     */

-    public String getServerAddress()  {

-        return serverAddress;

-    }

-

-    /**

-     * Set the {@link InetAddress} used for binding the local socket. Defaults

-     * to null, that is, the server binds to all available network interfaces

-     * 

-     * @param serverAddress

-     *            The local socket {@link InetAddress}

-     */

-    public void setServerAddress(String serverAddress) {

-        this.serverAddress = serverAddress;

-    }

-

-    /**

-     * Get the {@link SslConfiguration} used for listeners created by this factory

-     * 

-     * @return The {@link SslConfiguration}

-     */

-    public SslConfiguration getSslConfiguration() {

-        return ssl;

-    }

-

-    /**

-     * Set the {@link SslConfiguration} to use by listeners created by this factory

-     * @param ssl The {@link SslConfiguration}

-     */

-    public void setSslConfiguration(SslConfiguration ssl) {

-        this.ssl = ssl;

-    }

-

-    /**

-     * Get configuration for data connections made within listeners created by this factory

-     * 

-     * @return The data connection configuration

-     */

-    public DataConnectionConfiguration getDataConnectionConfiguration() {

-        return dataConnectionConfig;

-    }

-

-    /**

-     * Set configuration for data connections made within listeners created by this factory

-     * 

-     * @param dataConnectionConfig

-     *            The data connection configuration

-     */

-    public void setDataConnectionConfiguration(

-            DataConnectionConfiguration dataConnectionConfig) {

-        this.dataConnectionConfig = dataConnectionConfig;

-    }

-

-    /**

-     * Get the number of seconds during which no network activity 

-     * is allowed before a session is closed due to inactivity.  

-     * @return The idle time out

-     */

-    public int getIdleTimeout() {

-        return idleTimeout;

-    }

-

-    /**

-     * Set the number of seconds during which no network activity 

-     * is allowed before a session is closed due to inactivity.  

-     *

-     * @param idleTimeout The idle timeout in seconds

-     */

-    public void setIdleTimeout(int idleTimeout) {

-        this.idleTimeout = idleTimeout;

-    }

-

-    /**

-     * @deprecated Replaced by the IpFilter.    

-     * Retrieves the {@link InetAddress} for which listeners created by this factory blocks

-     * connections

-     * 

-     * @return The list of {@link InetAddress}es

-     */

-    @Deprecated

-    public List<InetAddress> getBlockedAddresses() {

-        return blockedAddresses;

-    }

-

-    /**

-     * @deprecated Replaced by the IpFilter.    

-     * Sets the {@link InetAddress} that listeners created by this factory will block from

-     * connecting

-     * 

-     * @param blockedAddresses

-     *            The list of {@link InetAddress}es

-     */

-    @Deprecated

-    public void setBlockedAddresses(List<InetAddress> blockedAddresses) {

-        this.blockedAddresses = blockedAddresses;

-    }

-

-    /**

-     * @deprecated Replaced by the IpFilter.    

-     * Retrives the {@link Subnet}s for which listeners created by this factory blocks connections

-     * 

-     * @return The list of {@link Subnet}s

-     */

-    @Deprecated

-    public List<Subnet> getBlockedSubnets() {

-        return blockedSubnets;

-    }

-

-    /**

-     * Sets the {@link Subnet}s that listeners created by this factory will block from connecting

-     * @param blockedSubnets 

-     *  The list of {@link Subnet}s

-     * @deprecated Replaced by the IpFilter.    

-     */

-    @Deprecated

-    public void setBlockedSubnets(List<Subnet> blockedSubnets) {

-        this.blockedSubnets = blockedSubnets;

-    }

-    

-    /**

-     * Returns the currently configured <code>SessionFilter</code>, if any.

-     * 

-     * @return the currently configured <code>SessionFilter</code>, if any.

-     *         Returns <code>null</code>, if no <code>SessionFilter</code> is

-     *         configured.

-     */

-    public SessionFilter getSessionFilter() {

-        return sessionFilter;

-    }

-

-    /**

-     * Sets the session filter to the given filter.

-     * 

-     * @param sessionFilter

-     *            the session filter.

-     */

-    public void setSessionFilter(SessionFilter sessionFilter) {

-        this.sessionFilter = sessionFilter;

-    }

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * 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.
+ */
+
+package org.apache.ftpserver.listener;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+
+import org.apache.ftpserver.DataConnectionConfiguration;
+import org.apache.ftpserver.DataConnectionConfigurationFactory;
+import org.apache.ftpserver.FtpServerConfigurationException;
+import org.apache.ftpserver.ipfilter.SessionFilter;
+import org.apache.ftpserver.listener.nio.NioListener;
+import org.apache.ftpserver.ssl.SslConfiguration;
+import org.apache.mina.filter.firewall.Subnet;
+
+/**
+ * Factory for listeners. Listeners themselves are immutable and must be 
+ * created using this factory.
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class ListenerFactory {
+
+    private String serverAddress;
+
+    private int port = 21;
+
+    private SslConfiguration ssl;
+
+    private boolean implicitSsl = false;
+
+    private DataConnectionConfiguration dataConnectionConfig = new DataConnectionConfigurationFactory()
+            .createDataConnectionConfiguration();
+
+    private int idleTimeout = 300;
+
+    private List<InetAddress> blockedAddresses;
+
+    private List<Subnet> blockedSubnets;
+    
+    /**
+     * The Session filter
+     */
+    private SessionFilter sessionFilter = null;
+
+    /**
+     * Default constructor
+     */
+    public ListenerFactory() {
+        // do nothing
+    }
+
+    /**
+     * Copy constructor, will copy properties from the provided listener.
+     * @param listener The listener which properties will be used for this factory
+     */
+    public ListenerFactory(Listener listener) {
+        serverAddress = listener.getServerAddress();
+        port = listener.getPort();
+        ssl = listener.getSslConfiguration();
+        implicitSsl = listener.isImplicitSsl();
+        dataConnectionConfig = listener.getDataConnectionConfiguration();
+        idleTimeout = listener.getIdleTimeout();
+        // TODO remove the next two lines if and when we remove the deprecated
+        // methods.
+        blockedAddresses = listener.getBlockedAddresses();
+        blockedSubnets = listener.getBlockedSubnets();
+        this.sessionFilter = listener.getSessionFilter();
+    }
+
+    /**
+     * Create a listener based on the settings of this factory. The listener is immutable.
+     * @return The created listener
+     */
+    public Listener createListener() {
+        try {
+            InetAddress.getByName(serverAddress);
+        } catch (UnknownHostException e) {
+            throw new FtpServerConfigurationException("Unknown host", e);
+        }
+        // Deal with the old style black list and new session Filter here.
+        if (sessionFilter != null) {
+            if (blockedAddresses != null || blockedSubnets != null) {
+                throw new IllegalStateException(
+                        "Usage of SessionFilter in combination with blockedAddesses/subnets is not supported. ");
+            }
+        }
+        if (blockedAddresses != null || blockedSubnets != null) {
+            return new NioListener(serverAddress, port, implicitSsl, ssl,
+                    dataConnectionConfig, idleTimeout, blockedAddresses,
+                    blockedSubnets);
+        } else {
+            return new NioListener(serverAddress, port, implicitSsl, ssl,
+                    dataConnectionConfig, idleTimeout, sessionFilter);
+        }
+    }
+
+    /**
+     * Is listeners created by this factory in SSL mode automatically or must the client explicitly
+     * request to use SSL
+     * 
+     * @return true is listeners created by this factory is automatically in SSL mode, false
+     *         otherwise
+     */
+    public boolean isImplicitSsl() {
+        return implicitSsl;
+    }
+
+    /**
+     * Should listeners created by this factory be in SSL mode automatically or must the client
+     * explicitly request to use SSL
+     * 
+     * @param implicitSsl
+     *            true is listeners created by this factory should automatically be in SSL mode,
+     *            false otherwise
+     */
+    public void setImplicitSsl(boolean implicitSsl) {
+        this.implicitSsl = implicitSsl;
+    }
+
+    /**
+     * Get the port on which listeners created by this factory is waiting for requests. 
+     * 
+     * @return The port
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Set the port on which listeners created by this factory will accept requests. Or set to 0
+     * (zero) is the port should be automatically assigned
+     * 
+     * @param port
+     *            The port to use.
+     */
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    /**
+     * Get the {@link InetAddress} used for binding the local socket. Defaults
+     * to null, that is, the server binds to all available network interfaces
+     * 
+     * @return The local socket {@link InetAddress}, if set
+     */
+    public String getServerAddress()  {
+        return serverAddress;
+    }
+
+    /**
+     * Set the {@link InetAddress} used for binding the local socket. Defaults
+     * to null, that is, the server binds to all available network interfaces
+     * 
+     * @param serverAddress
+     *            The local socket {@link InetAddress}
+     */
+    public void setServerAddress(String serverAddress) {
+        this.serverAddress = serverAddress;
+    }
+
+    /**
+     * Get the {@link SslConfiguration} used for listeners created by this factory
+     * 
+     * @return The {@link SslConfiguration}
+     */
+    public SslConfiguration getSslConfiguration() {
+        return ssl;
+    }
+
+    /**
+     * Set the {@link SslConfiguration} to use by listeners created by this factory
+     * @param ssl The {@link SslConfiguration}
+     */
+    public void setSslConfiguration(SslConfiguration ssl) {
+        this.ssl = ssl;
+    }
+
+    /**
+     * Get configuration for data connections made within listeners created by this factory
+     * 
+     * @return The data connection configuration
+     */
+    public DataConnectionConfiguration getDataConnectionConfiguration() {
+        return dataConnectionConfig;
+    }
+
+    /**
+     * Set configuration for data connections made within listeners created by this factory
+     * 
+     * @param dataConnectionConfig
+     *            The data connection configuration
+     */
+    public void setDataConnectionConfiguration(
+            DataConnectionConfiguration dataConnectionConfig) {
+        this.dataConnectionConfig = dataConnectionConfig;
+    }
+
+    /**
+     * Get the number of seconds during which no network activity 
+     * is allowed before a session is closed due to inactivity.  
+     * @return The idle time out
+     */
+    public int getIdleTimeout() {
+        return idleTimeout;
+    }
+
+    /**
+     * Set the number of seconds during which no network activity 
+     * is allowed before a session is closed due to inactivity.  
+     *
+     * @param idleTimeout The idle timeout in seconds
+     */
+    public void setIdleTimeout(int idleTimeout) {
+        this.idleTimeout = idleTimeout;
+    }
+
+    /**
+     * @deprecated Replaced by the IpFilter.    
+     * Retrieves the {@link InetAddress} for which listeners created by this factory blocks
+     * connections
+     * 
+     * @return The list of {@link InetAddress}es
+     */
+    @Deprecated
+    public List<InetAddress> getBlockedAddresses() {
+        return blockedAddresses;
+    }
+
+    /**
+     * @deprecated Replaced by the IpFilter.    
+     * Sets the {@link InetAddress} that listeners created by this factory will block from
+     * connecting
+     * 
+     * @param blockedAddresses
+     *            The list of {@link InetAddress}es
+     */
+    @Deprecated
+    public void setBlockedAddresses(List<InetAddress> blockedAddresses) {
+        this.blockedAddresses = blockedAddresses;
+    }
+
+    /**
+     * @deprecated Replaced by the IpFilter.    
+     * Retrives the {@link Subnet}s for which listeners created by this factory blocks connections
+     * 
+     * @return The list of {@link Subnet}s
+     */
+    @Deprecated
+    public List<Subnet> getBlockedSubnets() {
+        return blockedSubnets;
+    }
+
+    /**
+     * Sets the {@link Subnet}s that listeners created by this factory will block from connecting
+     * @param blockedSubnets 
+     *  The list of {@link Subnet}s
+     * @deprecated Replaced by the IpFilter.    
+     */
+    @Deprecated
+    public void setBlockedSubnets(List<Subnet> blockedSubnets) {
+        this.blockedSubnets = blockedSubnets;
+    }
+    
+    /**
+     * Returns the currently configured <code>SessionFilter</code>, if any.
+     * 
+     * @return the currently configured <code>SessionFilter</code>, if any.
+     *         Returns <code>null</code>, if no <code>SessionFilter</code> is
+     *         configured.
+     */
+    public SessionFilter getSessionFilter() {
+        return sessionFilter;
+    }
+
+    /**
+     * Sets the session filter to the given filter.
+     * 
+     * @param sessionFilter
+     *            the session filter.
+     */
+    public void setSessionFilter(SessionFilter sessionFilter) {
+        this.sessionFilter = sessionFilter;
+    }
 }
\ No newline at end of file
diff --git a/core/src/test/resources/users.properties b/core/src/test/resources/users.properties
index 30127a8..348eef8 100644
--- a/core/src/test/resources/users.properties
+++ b/core/src/test/resources/users.properties
@@ -1,57 +1,57 @@
-# Licensed to the Apache Software Foundation (ASF) under one

-# or more contributor license agreements.  See the NOTICE file

-# distributed with this work for additional information

-# regarding copyright ownership.  The ASF licenses this file

-# 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.

-

-#Generated file - don't edit (please)

-#Wed Feb 07 20:58:22 CET 2007

-

-ftpserver.user.admin.userpassword=admin

-ftpserver.user.admin.homedirectory=./test-tmp/ftproot

-ftpserver.user.admin.maxloginperip=0

-ftpserver.user.admin.idletime=0

-ftpserver.user.admin.enableflag=true

-ftpserver.user.admin.writepermission=true

-ftpserver.user.admin.maxloginnumber=0

-ftpserver.user.admin.uploadrate=0

-ftpserver.user.admin.downloadrate=0

-

-ftpserver.user.testuser1.homedirectory=./test-tmp/ftproot

-ftpserver.user.testuser1.maxloginnumber=3

-ftpserver.user.testuser1.writepermission=true

-ftpserver.user.testuser1.userpassword=password

-

-ftpserver.user.testuser2.userpassword=password

-ftpserver.user.testuser2.writepermission=true

-ftpserver.user.testuser2.homedirectory=./test-tmp/ftproot

-ftpserver.user.testuser2.maxloginperip=2

-

-ftpserver.user.testuser3.userpassword=

-ftpserver.user.testuser3.writepermission=true

-ftpserver.user.testuser3.homedirectory=./test-tmp/ftproot

-

-ftpserver.user.testuser4.userpassword=password

-ftpserver.user.testuser4.enableflag=false

-ftpserver.user.testuser4.homedirectory=./test-tmp/ftproot

-

-ftpserver.user.anonymous.userpassword=

-ftpserver.user.anonymous.maxloginperip=2

-ftpserver.user.anonymous.uploadrate=4800

-ftpserver.user.anonymous.writepermission=false

-ftpserver.user.anonymous.maxloginnumber=20

-ftpserver.user.anonymous.enableflag=true

-ftpserver.user.anonymous.homedirectory=./test-tmp/ftproot

-ftpserver.user.anonymous.idletime=300

-ftpserver.user.anonymous.downloadrate=4800

+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# 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.
+
+#Generated file - don't edit (please)
+#Wed Feb 07 20:58:22 CET 2007
+
+ftpserver.user.admin.userpassword=admin
+ftpserver.user.admin.homedirectory=./test-tmp/ftproot
+ftpserver.user.admin.maxloginperip=0
+ftpserver.user.admin.idletime=0
+ftpserver.user.admin.enableflag=true
+ftpserver.user.admin.writepermission=true
+ftpserver.user.admin.maxloginnumber=0
+ftpserver.user.admin.uploadrate=0
+ftpserver.user.admin.downloadrate=0
+
+ftpserver.user.testuser1.homedirectory=./test-tmp/ftproot
+ftpserver.user.testuser1.maxloginnumber=3
+ftpserver.user.testuser1.writepermission=true
+ftpserver.user.testuser1.userpassword=password
+
+ftpserver.user.testuser2.userpassword=password
+ftpserver.user.testuser2.writepermission=true
+ftpserver.user.testuser2.homedirectory=./test-tmp/ftproot
+ftpserver.user.testuser2.maxloginperip=2
+
+ftpserver.user.testuser3.userpassword=
+ftpserver.user.testuser3.writepermission=true
+ftpserver.user.testuser3.homedirectory=./test-tmp/ftproot
+
+ftpserver.user.testuser4.userpassword=password
+ftpserver.user.testuser4.enableflag=false
+ftpserver.user.testuser4.homedirectory=./test-tmp/ftproot
+
+ftpserver.user.anonymous.userpassword=
+ftpserver.user.anonymous.maxloginperip=2
+ftpserver.user.anonymous.uploadrate=4800
+ftpserver.user.anonymous.writepermission=false
+ftpserver.user.anonymous.maxloginnumber=20
+ftpserver.user.anonymous.enableflag=true
+ftpserver.user.anonymous.homedirectory=./test-tmp/ftproot
+ftpserver.user.anonymous.idletime=300
+ftpserver.user.anonymous.downloadrate=4800