/*
 * 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.commons.net.ftp;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Properties;
import java.util.Random;
import java.util.Set;

import org.apache.commons.net.MalformedServerReplyException;
import org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory;
import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
import org.apache.commons.net.ftp.parser.MLSxEntryParser;
import org.apache.commons.net.io.CRLFLineReader;
import org.apache.commons.net.io.CopyStreamAdapter;
import org.apache.commons.net.io.CopyStreamEvent;
import org.apache.commons.net.io.CopyStreamListener;
import org.apache.commons.net.io.FromNetASCIIInputStream;
import org.apache.commons.net.io.ToNetASCIIOutputStream;
import org.apache.commons.net.io.Util;

/**
 * FTPClient encapsulates all the functionality necessary to store and
 * retrieve files from an FTP server.  This class takes care of all
 * low level details of interacting with an FTP server and provides
 * a convenient higher level interface.  As with all classes derived
 * from {@link org.apache.commons.net.SocketClient},
 * you must first connect to the server with
 * {@link org.apache.commons.net.SocketClient#connect  connect }
 * before doing anything, and finally
 * {@link org.apache.commons.net.SocketClient#disconnect  disconnect }
 * after you're completely finished interacting with the server.
 * Then you need to check the FTP reply code to see if the connection
 * was successful.  For example:
 * <pre>
 *    FTPClient ftp = new FTPClient();
 *    FTPClientConfig config = new FTPClientConfig();
 *    config.setXXX(YYY); // change required options
 *    // for example config.setServerTimeZoneId("Pacific/Pitcairn")
 *    ftp.configure(config );
 *    boolean error = false;
 *    try {
 *      int reply;
 *      String server = "ftp.example.com";
 *      ftp.connect(server);
 *      System.out.println("Connected to " + server + ".");
 *      System.out.print(ftp.getReplyString());
 *
 *      // After connection attempt, you should check the reply code to verify
 *      // success.
 *      reply = ftp.getReplyCode();
 *
 *      if(!FTPReply.isPositiveCompletion(reply)) {
 *        ftp.disconnect();
 *        System.err.println("FTP server refused connection.");
 *        System.exit(1);
 *      }
 *      ... // transfer files
 *      ftp.logout();
 *    } catch(IOException e) {
 *      error = true;
 *      e.printStackTrace();
 *    } finally {
 *      if(ftp.isConnected()) {
 *        try {
 *          ftp.disconnect();
 *        } catch(IOException ioe) {
 *          // do nothing
 *        }
 *      }
 *      System.exit(error ? 1 : 0);
 *    }
 * </pre>
 * <p>
 * Immediately after connecting is the only real time you need to check the
 * reply code (because connect is of type void).  The convention for all the
 * FTP command methods in FTPClient is such that they either return a
 * boolean value or some other value.
 * The boolean methods return true on a successful completion reply from
 * the FTP server and false on a reply resulting in an error condition or
 * failure.  The methods returning a value other than boolean return a value
 * containing the higher level data produced by the FTP command, or null if a
 * reply resulted in an error condition or failure.  If you want to access
 * the exact FTP reply code causing a success or failure, you must call
 * {@link org.apache.commons.net.ftp.FTP#getReplyCode  getReplyCode } after
 * a success or failure.
 * <p>
 * The default settings for FTPClient are for it to use
 * <code> FTP.ASCII_FILE_TYPE </code>,
 * <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
 * <code> FTP.STREAM_TRANSFER_MODE </code>, and
 * <code> FTP.FILE_STRUCTURE </code>.  The only file types directly supported
 * are <code> FTP.ASCII_FILE_TYPE </code> and
 * <code> FTP.BINARY_FILE_TYPE </code>.  Because there are at least 4
 * different EBCDIC encodings, we have opted not to provide direct support
 * for EBCDIC.  To transfer EBCDIC and other unsupported file types you
 * must create your own filter InputStreams and OutputStreams and wrap
 * them around the streams returned or required by the FTPClient methods.
 * FTPClient uses the {@link ToNetASCIIOutputStream NetASCII}
 * filter streams to provide transparent handling of ASCII files.  We will
 * consider incorporating EBCDIC support if there is enough demand.
 * <p>
 * <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
 * <code> FTP.STREAM_TRANSFER_MODE </code>, and
 * <code> FTP.FILE_STRUCTURE </code> are the only supported formats,
 * transfer modes, and file structures.
 * <p>
 * Because the handling of sockets on different platforms can differ
 * significantly, the FTPClient automatically issues a new PORT (or EPRT) command
 * prior to every transfer requiring that the server connect to the client's
 * data port.  This ensures identical problem-free behavior on Windows, Unix,
 * and Macintosh platforms.  Additionally, it relieves programmers from
 * having to issue the PORT (or EPRT) command themselves and dealing with platform
 * dependent issues.
 * <p>
 * Additionally, for security purposes, all data connections to the
 * client are verified to ensure that they originated from the intended
 * party (host and port).  If a data connection is initiated by an unexpected
 * party, the command will close the socket and throw an IOException.  You
 * may disable this behavior with
 * {@link #setRemoteVerificationEnabled setRemoteVerificationEnabled()}.
 * <p>
 * You should keep in mind that the FTP server may choose to prematurely
 * close a connection if the client has been idle for longer than a
 * given time period (usually 900 seconds).  The FTPClient class will detect a
 * premature FTP server connection closing when it receives a
 * {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
 *  response to a command.
 * When that occurs, the FTP class method encountering that reply will throw
 * an {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
 * .
 * <code>FTPConnectionClosedException</code>
 * is a subclass of <code> IOException </code> and therefore need not be
 * caught separately, but if you are going to catch it separately, its
 * catch block must appear before the more general <code> IOException </code>
 * catch block.  When you encounter an
 * {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
 * , you must disconnect the connection with
 * {@link #disconnect  disconnect() } to properly clean up the
 * system resources used by FTPClient.  Before disconnecting, you may check the
 * last reply code and text with
 * {@link org.apache.commons.net.ftp.FTP#getReplyCode  getReplyCode },
 * {@link org.apache.commons.net.ftp.FTP#getReplyString  getReplyString },
 * and
 * {@link org.apache.commons.net.ftp.FTP#getReplyStrings  getReplyStrings}.
 * You may avoid server disconnections while the client is idle by
 * periodically sending NOOP commands to the server.
 * <p>
 * Rather than list it separately for each method, we mention here that
 * every method communicating with the server and throwing an IOException
 * can also throw a
 * {@link org.apache.commons.net.MalformedServerReplyException}
 * , which is a subclass
 * of IOException.  A MalformedServerReplyException will be thrown when
 * the reply received from the server deviates enough from the protocol
 * specification that it cannot be interpreted in a useful manner despite
 * attempts to be as lenient as possible.
 * <p>
 * Listing API Examples
 * Both paged and unpaged examples of directory listings are available,
 * as follows:
 * <p>
 * Unpaged (whole list) access, using a parser accessible by auto-detect:
 * <pre>
 *    FTPClient f = new FTPClient();
 *    f.connect(server);
 *    f.login(username, password);
 *    FTPFile[] files = f.listFiles(directory);
 * </pre>
 * <p>
 * Paged access, using a parser not accessible by auto-detect.  The class
 * defined in the first parameter of initateListParsing should be derived
 * from org.apache.commons.net.FTPFileEntryParser:
 * <pre>
 *    FTPClient f = new FTPClient();
 *    f.connect(server);
 *    f.login(username, password);
 *    FTPListParseEngine engine =
 *       f.initiateListParsing("com.whatever.YourOwnParser", directory);
 *
 *    while (engine.hasNext()) {
 *       FTPFile[] files = engine.getNext(25);  // "page size" you want
 *       //do whatever you want with these files, display them, etc.
 *       //expensive FTPFile objects not created until needed.
 *    }
 * </pre>
 * <p>
 * Paged access, using a parser accessible by auto-detect:
 * <pre>
 *    FTPClient f = new FTPClient();
 *    f.connect(server);
 *    f.login(username, password);
 *    FTPListParseEngine engine = f.initiateListParsing(directory);
 *
 *    while (engine.hasNext()) {
 *       FTPFile[] files = engine.getNext(25);  // "page size" you want
 *       //do whatever you want with these files, display them, etc.
 *       //expensive FTPFile objects not created until needed.
 *    }
 * </pre>
 * <p>
 * For examples of using FTPClient on servers whose directory listings
 * <ul>
 * <li>use languages other than English</li>
 * <li>use date formats other than the American English "standard" <code>MM d yyyy</code></li>
 * <li>are in different timezones and you need accurate timestamps for dependency checking
 *     as in Ant</li>
 * </ul>see {@link  FTPClientConfig  FTPClientConfig}.
 * <p>
 * <b>Control channel keep-alive feature</b>:
 * <p>
 * <b>Please note:</b> this does not apply to the methods where the user is responsible for writing or reading
 * the data stream, i.e. {@link #retrieveFileStream(String)} , {@link #storeFileStream(String)}
 * and the other xxxFileStream methods
 * <p>
 * During file transfers, the data connection is busy, but the control connection is idle.
 * FTP servers know that the control connection is in use, so won't close it through lack of activity,
 * but it's a lot harder for network routers to know that the control and data connections are associated
 * with each other.
 * Some routers may treat the control connection as idle, and disconnect it if the transfer over the data
 * connection takes longer than the allowable idle time for the router.
 * <br>
 * One solution to this is to send a safe command (i.e. NOOP) over the control connection to reset the router's
 * idle timer. This is enabled as follows:
 * <pre>
 *     ftpClient.setControlKeepAliveTimeout(300); // set timeout to 5 minutes
 * </pre>
 * This will cause the file upload/download methods to send a NOOP approximately every 5 minutes.
 * The following public methods support this:
 * <ul>
 * <li>{@link #retrieveFile(String, OutputStream)}</li>
 * <li>{@link #appendFile(String, InputStream)}</li>
 * <li>{@link #storeFile(String, InputStream)}</li>
 * <li>{@link #storeUniqueFile(InputStream)}</li>
 * <li>{@link #storeUniqueFileStream(String)}</li>
 * </ul>
 * This feature does not apply to the methods where the user is responsible for writing or reading
 * the data stream, i.e. {@link #retrieveFileStream(String)} , {@link #storeFileStream(String)}
 * and the other xxxFileStream methods.
 * In such cases, the user is responsible for keeping the control connection alive if necessary.
 * <p>
 * The implementation currently uses a {@link CopyStreamListener} which is passed to the
 * {@link Util#copyStream(InputStream, OutputStream, int, long, CopyStreamListener, boolean)}
 * method, so the timing is partially dependent on how long each block transfer takes.
 * <p>
 * <b>This keep-alive feature is optional; if it does not help or causes problems then don't use it.</b>
 * <p>
 * @see #FTP_SYSTEM_TYPE
 * @see #SYSTEM_TYPE_PROPERTIES
 * @see FTP
 * @see FTPConnectionClosedException
 * @see FTPFileEntryParser
 * @see FTPFileEntryParserFactory
 * @see DefaultFTPFileEntryParserFactory
 * @see FTPClientConfig
 *
 * @see org.apache.commons.net.MalformedServerReplyException
 */
public class FTPClient extends FTP
implements Configurable
{
    /**
     * The system property ({@value}) which can be used to override the system type.<br>
     * If defined, the value will be used to create any automatically created parsers.
     *
     * @since 3.0
     */
    public static final String FTP_SYSTEM_TYPE = "org.apache.commons.net.ftp.systemType";

    /**
     * The system property ({@value}) which can be used as the default system type.<br>
     * If defined, the value will be used if the SYST command fails.
     *
     * @since 3.1
     */
    public static final String FTP_SYSTEM_TYPE_DEFAULT = "org.apache.commons.net.ftp.systemType.default";

    /**
     * The name of an optional systemType properties file ({@value}), which is loaded
     * using {@link Class#getResourceAsStream(String)}.<br>
     * The entries are the systemType (as determined by {@link FTPClient#getSystemType})
     * and the values are the replacement type or parserClass, which is passed to
     * {@link FTPFileEntryParserFactory#createFileEntryParser(String)}.<br>
     * For example:
     * <pre>
     * Plan 9=Unix
     * OS410=org.apache.commons.net.ftp.parser.OS400FTPEntryParser
     * </pre>
     *
     * @since 3.0
     */
    public static final String SYSTEM_TYPE_PROPERTIES = "/systemType.properties";

    /**
     * A constant indicating the FTP session is expecting all transfers
     * to occur between the client (local) and server and that the server
     * should connect to the client's data port to initiate a data transfer.
     * This is the default data connection mode when and FTPClient instance
     * is created.
     */
    public static final int ACTIVE_LOCAL_DATA_CONNECTION_MODE = 0;
    /**
     * A constant indicating the FTP session is expecting all transfers
     * to occur between two remote servers and that the server
     * the client is connected to should connect to the other server's
     * data port to initiate a data transfer.
     */
    public static final int ACTIVE_REMOTE_DATA_CONNECTION_MODE = 1;
    /**
     * A constant indicating the FTP session is expecting all transfers
     * to occur between the client (local) and server and that the server
     * is in passive mode, requiring the client to connect to the
     * server's data port to initiate a transfer.
     */
    public static final int PASSIVE_LOCAL_DATA_CONNECTION_MODE = 2;
    /**
     * A constant indicating the FTP session is expecting all transfers
     * to occur between two remote servers and that the server
     * the client is connected to is in passive mode, requiring the other
     * server to connect to the first server's data port to initiate a data
     * transfer.
     */
    public static final int PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3;

    private int __dataConnectionMode;
    private int __dataTimeout;
    private int __passivePort;
    private String __passiveHost;
    private final Random __random;
    private int __activeMinPort;
    private int __activeMaxPort;
    private InetAddress __activeExternalHost;
    private InetAddress __reportActiveExternalHost; // overrides __activeExternalHost in EPRT/PORT commands
    /** The address to bind to on passive connections, if necessary. */
    private InetAddress __passiveLocalHost;

    private int __fileType;
    @SuppressWarnings("unused") // fields are written, but currently not read
    private int __fileFormat;
    @SuppressWarnings("unused") // field is written, but currently not read
    private int __fileStructure;
    @SuppressWarnings("unused") // field is written, but currently not read
    private int __fileTransferMode;
    private boolean __remoteVerificationEnabled;
    private long __restartOffset;
    private FTPFileEntryParserFactory __parserFactory;
    private int __bufferSize; // buffersize for buffered data streams
    private int __sendDataSocketBufferSize;
    private int __receiveDataSocketBufferSize;
    private boolean __listHiddenFiles;
    private boolean __useEPSVwithIPv4; // whether to attempt EPSV with an IPv4 connection

    // __systemName is a cached value that should not be referenced directly
    // except when assigned in getSystemName and __initDefaults.
    private String __systemName;

    // __entryParser is a cached value that should not be referenced directly
    // except when assigned in listFiles(String, String) and __initDefaults.
    private FTPFileEntryParser __entryParser;

    // Key used to create the parser; necessary to ensure that the parser type is not ignored
    private String __entryParserKey;

    private FTPClientConfig __configuration;

    // Listener used by store/retrieve methods to handle keepalive
    private CopyStreamListener __copyStreamListener;

    // How long to wait before sending another control keep-alive message
    private long __controlKeepAliveTimeout;

    // How long to wait (ms) for keepalive message replies before continuing
    // Most FTP servers don't seem to support concurrent control and data connection usage
    private int __controlKeepAliveReplyTimeout=1000;

    // Debug counts for NOOP acks
    private int[] __cslDebug;

    /**
     * Enable or disable replacement of internal IP in passive mode. Default enabled
     * using {code NatServerResolverImpl}.
     */
    private HostnameResolver __passiveNatWorkaroundStrategy = new NatServerResolverImpl(this);

    /** Pattern for PASV mode responses. Groups: (n,n,n,n),(n),(n) */
    private static final java.util.regex.Pattern __PARMS_PAT;

    static {
        __PARMS_PAT = java.util.regex.Pattern.compile(
                "(\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}),(\\d{1,3}),(\\d{1,3})");
    }

    /** Controls the automatic server encoding detection (only UTF-8 supported). */
    private boolean __autodetectEncoding = false;

    /** Map of FEAT responses. If null, has not been initialised. */
    private HashMap<String, Set<String>> __featuresMap;

    private static class PropertiesSingleton {

        static final Properties PROPERTIES;

        static {
            InputStream resourceAsStream = FTPClient.class.getResourceAsStream(SYSTEM_TYPE_PROPERTIES);
            Properties p = null;
            if (resourceAsStream != null) {
                p = new Properties();
                try {
                    p.load(resourceAsStream);
                } catch (IOException e) {
                    // Ignored
                } finally {
                    try {
                        resourceAsStream.close();
                    } catch (IOException e) {
                        // Ignored
                    }
                }
            }
            PROPERTIES = p;
        }

    }
    private static Properties getOverrideProperties(){
        return PropertiesSingleton.PROPERTIES;
    }

    /**
     * Default FTPClient constructor.  Creates a new FTPClient instance
     * with the data connection mode set to
     * <code> ACTIVE_LOCAL_DATA_CONNECTION_MODE </code>, the file type
     * set to <code> FTP.ASCII_FILE_TYPE </code>, the
     * file format set to <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
     * the file structure set to <code> FTP.FILE_STRUCTURE </code>, and
     * the transfer mode set to <code> FTP.STREAM_TRANSFER_MODE </code>.
     * <p>
     * The list parsing auto-detect feature can be configured to use lenient future
     * dates (short dates may be up to one day in the future) as follows:
     * <pre>
     * FTPClient ftp = new FTPClient();
     * FTPClientConfig config = new FTPClientConfig();
     * config.setLenientFutureDates(true);
     * ftp.configure(config );
     * </pre>
     */
    public FTPClient()
    {
        __initDefaults();
        __dataTimeout = -1;
        __remoteVerificationEnabled = true;
        __parserFactory = new DefaultFTPFileEntryParserFactory();
        __configuration      = null;
        __listHiddenFiles = false;
        __useEPSVwithIPv4 = false;
        __random = new Random();
        __passiveLocalHost   = null;
    }


    private void __initDefaults()
    {
        __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
        __passiveHost        = null;
        __passivePort        = -1;
        __activeExternalHost = null;
        __reportActiveExternalHost = null;
        __activeMinPort = 0;
        __activeMaxPort = 0;
        __fileType           = FTP.ASCII_FILE_TYPE;
        __fileStructure      = FTP.FILE_STRUCTURE;
        __fileFormat         = FTP.NON_PRINT_TEXT_FORMAT;
        __fileTransferMode   = FTP.STREAM_TRANSFER_MODE;
        __restartOffset      = 0;
        __systemName         = null;
        __entryParser        = null;
        __entryParserKey    = "";
        __featuresMap = null;
    }

    /**
     * Parse the pathname from a CWD reply.
     * <p>
     * According to RFC959 (http://www.ietf.org/rfc/rfc959.txt),
     * it should be the same as for MKD i.e.
     * {@code 257<space>"<directory-name>"[<space>commentary]}
     * where any double-quotes in {@code <directory-name>} are doubled.
     * Unlike MKD, the commentary is optional.
     * <p>
     * However, see NET-442 for an exception.
     *
     * @param reply
     * @return the pathname, without enclosing quotes,
     * or the full string after the reply code and space if the syntax is invalid
     * (i.e. enclosing quotes are missing or embedded quotes are not doubled)
     */
    // package protected for access by test cases
    static String __parsePathname(String reply)
    {
        String param = reply.substring(REPLY_CODE_LEN + 1);
        if (param.startsWith("\"")) {
            StringBuilder sb = new StringBuilder();
            boolean quoteSeen = false;
            // start after initial quote
            for(int i=1; i < param.length(); i++) {
                char ch = param.charAt(i);
                if (ch=='"') {
                    if (quoteSeen) {
                        sb.append(ch);
                        quoteSeen=false;
                    } else {
                        // don't output yet, in case doubled
                        quoteSeen=true;
                    }
                } else {
                    if (quoteSeen) { // found lone trailing quote within string
                        return sb.toString();
                    }
                    sb.append(ch); // just another character
                }
            }
            if (quoteSeen) { // found lone trailing quote at end of string
                return sb.toString();
            }
        }
        // malformed reply, return all after reply code and space
        return param;
    }

    /**
     * @since 3.1
     * @param reply the reply to parse
     * @throws MalformedServerReplyException if the server reply does not match  (n,n,n,n),(n),(n)
     */
    protected void _parsePassiveModeReply(String reply)
    throws MalformedServerReplyException
    {
        java.util.regex.Matcher m = __PARMS_PAT.matcher(reply);
        if (!m.find()) {
            throw new MalformedServerReplyException(
                    "Could not parse passive host information.\nServer Reply: " + reply);
        }

        __passiveHost = m.group(1).replace(',', '.'); // Fix up to look like IP address

        try
        {
            int oct1 = Integer.parseInt(m.group(2));
            int oct2 = Integer.parseInt(m.group(3));
            __passivePort = (oct1 << 8) | oct2;
        }
        catch (NumberFormatException e)
        {
            throw new MalformedServerReplyException(
                    "Could not parse passive port information.\nServer Reply: " + reply);
        }

        if (__passiveNatWorkaroundStrategy != null) {
            try {
                String passiveHost = __passiveNatWorkaroundStrategy.resolve(__passiveHost);
                if (!__passiveHost.equals(passiveHost)) {
                    fireReplyReceived(0,
                            "[Replacing PASV mode reply address "+__passiveHost+" with "+passiveHost+"]\n");
                    __passiveHost = passiveHost;
                }
            } catch (UnknownHostException e) { // Should not happen as we are passing in an IP address
                throw new MalformedServerReplyException(
                        "Could not parse passive host information.\nServer Reply: " + reply);
            }
        }
    }

    protected void _parseExtendedPassiveModeReply(String reply)
    throws MalformedServerReplyException
    {
        reply = reply.substring(reply.indexOf('(') + 1,
                reply.indexOf(')')).trim();

        char delim1, delim2, delim3, delim4;
        delim1 = reply.charAt(0);
        delim2 = reply.charAt(1);
        delim3 = reply.charAt(2);
        delim4 = reply.charAt(reply.length()-1);

        if (!(delim1 == delim2) || !(delim2 == delim3)
                || !(delim3 == delim4)) {
            throw new MalformedServerReplyException(
                    "Could not parse extended passive host information.\nServer Reply: " + reply);
        }

        int port;
        try
        {
            port = Integer.parseInt(reply.substring(3, reply.length()-1));
        }
        catch (NumberFormatException e)
        {
            throw new MalformedServerReplyException(
                    "Could not parse extended passive host information.\nServer Reply: " + reply);
        }


        // in EPSV mode, the passive host address is implicit
        __passiveHost = getRemoteAddress().getHostAddress();
        __passivePort = port;
    }

    private boolean __storeFile(FTPCmd command, String remote, InputStream local)
    throws IOException
    {
        return _storeFile(command.getCommand(), remote, local);
    }

    /**
     * @since 3.1
     * @param command the command to send
     * @param remote the remote file name
     * @param local The local InputStream from which to read the data to
     *                be written/appended to the remote file.
     * @return true if successful
     * @throws IOException on error
     */
    protected boolean _storeFile(String command, String remote, InputStream local)
    throws IOException
    {
        Socket socket = _openDataConnection_(command, remote);

        if (socket == null) {
            return false;
        }

        final OutputStream output;

        if (__fileType == ASCII_FILE_TYPE) {
            output = new ToNetASCIIOutputStream(getBufferedOutputStream(socket.getOutputStream()));
        } else {
            output = getBufferedOutputStream(socket.getOutputStream());
        }

        CSL csl = null;
        if (__controlKeepAliveTimeout > 0) {
            csl = new CSL(this, __controlKeepAliveTimeout, __controlKeepAliveReplyTimeout);
        }

        // Treat everything else as binary for now
        try
        {
            Util.copyStream(local, output, getBufferSize(),
                    CopyStreamEvent.UNKNOWN_STREAM_SIZE, __mergeListeners(csl),
                    false);
            output.close(); // ensure the file is fully written
            socket.close(); // done writing the file

            // Get the transfer response
            return completePendingCommand();
        }
        catch (IOException e)
        {
            Util.closeQuietly(output); // ignore close errors here
            Util.closeQuietly(socket); // ignore close errors here
            throw e;
        } finally {
            if (csl != null) {
                __cslDebug = csl.cleanUp(); // fetch any outstanding keepalive replies
            }
        }
    }

    private OutputStream __storeFileStream(FTPCmd command, String remote)
    throws IOException
    {
        return _storeFileStream(command.getCommand(), remote);
    }

    /**
     * @param command the command to send
     * @param remote the remote file name
     * @return the output stream to write to
     * @throws IOException on error
     * @since 3.1
     */
    protected OutputStream _storeFileStream(String command, String remote)
    throws IOException
    {
        Socket socket = _openDataConnection_(command, remote);

        if (socket == null) {
            return null;
        }

        final OutputStream output;
        if (__fileType == ASCII_FILE_TYPE) {
            // We buffer ascii transfers because the buffering has to
            // be interposed between ToNetASCIIOutputSream and the underlying
            // socket output stream.  We don't buffer binary transfers
            // because we don't want to impose a buffering policy on the
            // programmer if possible.  Programmers can decide on their
            // own if they want to wrap the SocketOutputStream we return
            // for file types other than ASCII.
            output = new ToNetASCIIOutputStream(getBufferedOutputStream(socket.getOutputStream()));
        } else {
            output = socket.getOutputStream();
        }
        return new org.apache.commons.net.io.SocketOutputStream(socket, output);
    }


    /**
     * Establishes a data connection with the FTP server, returning
     * a Socket for the connection if successful.  If a restart
     * offset has been set with {@link #setRestartOffset(long)},
     * a REST command is issued to the server with the offset as
     * an argument before establishing the data connection.  Active
     * mode connections also cause a local PORT command to be issued.
     *
     * @param command  The int representation of the FTP command to send.
     * @param arg The arguments to the FTP command.  If this parameter is
     *             set to null, then the command is sent with no argument.
     * @return A Socket corresponding to the established data connection.
     *         Null is returned if an FTP protocol error is reported at
     *         any point during the establishment and initialization of
     *         the connection.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     * @deprecated (3.3) Use {@link #_openDataConnection_(FTPCmd, String)} instead
     */
    @Deprecated
    protected Socket _openDataConnection_(int command, String arg)
    throws IOException
    {
        return _openDataConnection_(FTPCommand.getCommand(command), arg);
    }

    /**
     * Establishes a data connection with the FTP server, returning
     * a Socket for the connection if successful.  If a restart
     * offset has been set with {@link #setRestartOffset(long)},
     * a REST command is issued to the server with the offset as
     * an argument before establishing the data connection.  Active
     * mode connections also cause a local PORT command to be issued.
     *
     * @param command  The int representation of the FTP command to send.
     * @param arg The arguments to the FTP command.  If this parameter is
     *             set to null, then the command is sent with no argument.
     * @return A Socket corresponding to the established data connection.
     *         Null is returned if an FTP protocol error is reported at
     *         any point during the establishment and initialization of
     *         the connection.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     * @since 3.3
     */
    protected Socket _openDataConnection_(FTPCmd command, String arg)
    throws IOException
    {
        return _openDataConnection_(command.getCommand(), arg);
    }

    /**
     * Establishes a data connection with the FTP server, returning
     * a Socket for the connection if successful.  If a restart
     * offset has been set with {@link #setRestartOffset(long)},
     * a REST command is issued to the server with the offset as
     * an argument before establishing the data connection.  Active
     * mode connections also cause a local PORT command to be issued.
     *
     * @param command  The text representation of the FTP command to send.
     * @param arg The arguments to the FTP command.  If this parameter is
     *             set to null, then the command is sent with no argument.
     * @return A Socket corresponding to the established data connection.
     *         Null is returned if an FTP protocol error is reported at
     *         any point during the establishment and initialization of
     *         the connection.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     * @since 3.1
     */
    protected Socket _openDataConnection_(String command, String arg)
    throws IOException
    {
        if (__dataConnectionMode != ACTIVE_LOCAL_DATA_CONNECTION_MODE &&
                __dataConnectionMode != PASSIVE_LOCAL_DATA_CONNECTION_MODE) {
            return null;
        }

        final boolean isInet6Address = getRemoteAddress() instanceof Inet6Address;

        Socket socket;

        if (__dataConnectionMode == ACTIVE_LOCAL_DATA_CONNECTION_MODE)
        {
            // if no activePortRange was set (correctly) -> getActivePort() = 0
            // -> new ServerSocket(0) -> bind to any free local port
            ServerSocket server = _serverSocketFactory_.createServerSocket(getActivePort(), 1, getHostAddress());

            try {
                // Try EPRT only if remote server is over IPv6, if not use PORT,
                // because EPRT has no advantage over PORT on IPv4.
                // It could even have the disadvantage,
                // that EPRT will make the data connection fail, because
                // today's intelligent NAT Firewalls are able to
                // substitute IP addresses in the PORT command,
                // but might not be able to recognize the EPRT command.
                if (isInet6Address) {
                    if (!FTPReply.isPositiveCompletion(eprt(getReportHostAddress(), server.getLocalPort()))) {
                        return null;
                    }
                } else {
                    if (!FTPReply.isPositiveCompletion(port(getReportHostAddress(), server.getLocalPort()))) {
                        return null;
                    }
                }

                if ((__restartOffset > 0) && !restart(__restartOffset)) {
                    return null;
                }

                if (!FTPReply.isPositivePreliminary(sendCommand(command, arg))) {
                    return null;
                }

                // For now, let's just use the data timeout value for waiting for
                // the data connection.  It may be desirable to let this be a
                // separately configurable value.  In any case, we really want
                // to allow preventing the accept from blocking indefinitely.
                if (__dataTimeout >= 0) {
                    server.setSoTimeout(__dataTimeout);
                }
                socket = server.accept();

                // Ensure the timeout is set before any commands are issued on the new socket
                if (__dataTimeout >= 0) {
                    socket.setSoTimeout(__dataTimeout);
                }
                if (__receiveDataSocketBufferSize > 0) {
                    socket.setReceiveBufferSize(__receiveDataSocketBufferSize);
                }
                if (__sendDataSocketBufferSize > 0) {
                    socket.setSendBufferSize(__sendDataSocketBufferSize);
                }
            } finally {
                server.close();
            }
        }
        else
        { // We must be in PASSIVE_LOCAL_DATA_CONNECTION_MODE

            // Try EPSV command first on IPv6 - and IPv4 if enabled.
            // When using IPv4 with NAT it has the advantage
            // to work with more rare configurations.
            // E.g. if FTP server has a static PASV address (external network)
            // and the client is coming from another internal network.
            // In that case the data connection after PASV command would fail,
            // while EPSV would make the client succeed by taking just the port.
            boolean attemptEPSV = isUseEPSVwithIPv4() || isInet6Address;
            if (attemptEPSV && epsv() == FTPReply.ENTERING_EPSV_MODE)
            {
                _parseExtendedPassiveModeReply(_replyLines.get(0));
            }
            else
            {
                if (isInet6Address) {
                    return null; // Must use EPSV for IPV6
                }
                // If EPSV failed on IPV4, revert to PASV
                if (pasv() != FTPReply.ENTERING_PASSIVE_MODE) {
                    return null;
                }
                _parsePassiveModeReply(_replyLines.get(0));
            }

            socket = _socketFactory_.createSocket();
            if (__receiveDataSocketBufferSize > 0) {
                socket.setReceiveBufferSize(__receiveDataSocketBufferSize);
            }
            if (__sendDataSocketBufferSize > 0) {
                socket.setSendBufferSize(__sendDataSocketBufferSize);
            }
            if (__passiveLocalHost != null) {
                socket.bind(new InetSocketAddress(__passiveLocalHost, 0));
            }

            // For now, let's just use the data timeout value for waiting for
            // the data connection.  It may be desirable to let this be a
            // separately configurable value.  In any case, we really want
            // to allow preventing the accept from blocking indefinitely.
            if (__dataTimeout >= 0) {
                socket.setSoTimeout(__dataTimeout);
            }

            socket.connect(new InetSocketAddress(__passiveHost, __passivePort), connectTimeout);
            if ((__restartOffset > 0) && !restart(__restartOffset))
            {
                socket.close();
                return null;
            }

            if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
            {
                socket.close();
                return null;
            }
        }

        if (__remoteVerificationEnabled && !verifyRemote(socket))
        {
            socket.close();

            throw new IOException(
                    "Host attempting data connection " + socket.getInetAddress().getHostAddress() +
                    " is not same as server " + getRemoteAddress().getHostAddress());
        }

        return socket;
    }


    @Override
    protected void _connectAction_() throws IOException
    {
        _connectAction_(null);
    }


    /**
     * @param socketIsReader the reader to reuse (if non-null)
     * @throws IOException on error
     * @since 3.4
     */
    @Override
    protected void _connectAction_(Reader socketIsReader) throws IOException
    {
        super._connectAction_(socketIsReader); // sets up _input_ and _output_
        __initDefaults();
        // must be after super._connectAction_(), because otherwise we get an
        // Exception claiming we're not connected
        if ( __autodetectEncoding )
        {
            ArrayList<String> oldReplyLines = new ArrayList<String> (_replyLines);
            int oldReplyCode = _replyCode;
            if ( hasFeature("UTF8") || hasFeature("UTF-8")) // UTF8 appears to be the default
            {
                 setControlEncoding("UTF-8");
                 _controlInput_ =
                     new CRLFLineReader(new InputStreamReader(_input_, getControlEncoding()));
                 _controlOutput_ =
                    new BufferedWriter(new OutputStreamWriter(_output_, getControlEncoding()));
            }
            // restore the original reply (server greeting)
            _replyLines.clear();
            _replyLines.addAll(oldReplyLines);
            _replyCode = oldReplyCode;
            _newReplyString = true;
        }
    }


    /**
     * Sets the timeout in milliseconds to use when reading from the
     * data connection.  This timeout will be set immediately after
     * opening the data connection, provided that the value is &ge; 0.
     * <p>
     * <b>Note:</b> the timeout will also be applied when calling accept()
     * whilst establishing an active local data connection.
     * @param  timeout The default timeout in milliseconds that is used when
     *        opening a data connection socket. The value 0 means an infinite timeout.
     */
    public void setDataTimeout(int timeout)
    {
        __dataTimeout = timeout;
    }

    /**
     * set the factory used for parser creation to the supplied factory object.
     *
     * @param parserFactory
     *               factory object used to create FTPFileEntryParsers
     *
     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
     */
    public void setParserFactory(FTPFileEntryParserFactory parserFactory) {
        __parserFactory = parserFactory;
    }


    /**
     * Closes the connection to the FTP server and restores
     * connection parameters to the default values.
     *
     * @throws IOException If an error occurs while disconnecting.
     */
    @Override
    public void disconnect() throws IOException
    {
        super.disconnect();
        __initDefaults();
    }


    /**
     * Enable or disable verification that the remote host taking part
     * of a data connection is the same as the host to which the control
     * connection is attached.  The default is for verification to be
     * enabled.  You may set this value at any time, whether the
     * FTPClient is currently connected or not.
     *
     * @param enable True to enable verification, false to disable verification.
     */
    public void setRemoteVerificationEnabled(boolean enable)
    {
        __remoteVerificationEnabled = enable;
    }

    /**
     * Return whether or not verification of the remote host participating
     * in data connections is enabled.  The default behavior is for
     * verification to be enabled.
     *
     * @return True if verification is enabled, false if not.
     */
    public boolean isRemoteVerificationEnabled()
    {
        return __remoteVerificationEnabled;
    }

    /**
     * Login to the FTP server using the provided username and password.
     *
     * @param username The username to login under.
     * @param password The password to use.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean login(String username, String password) throws IOException
    {

        user(username);

        if (FTPReply.isPositiveCompletion(_replyCode)) {
            return true;
        }

        // If we get here, we either have an error code, or an intermmediate
        // reply requesting password.
        if (!FTPReply.isPositiveIntermediate(_replyCode)) {
            return false;
        }

        return FTPReply.isPositiveCompletion(pass(password));
    }


    /**
     * Login to the FTP server using the provided username, password,
     * and account.  If no account is required by the server, only
     * the username and password, the account information is not used.
     *
     * @param username The username to login under.
     * @param password The password to use.
     * @param account  The account to use.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean login(String username, String password, String account)
    throws IOException
    {
        user(username);

        if (FTPReply.isPositiveCompletion(_replyCode)) {
            return true;
        }

        // If we get here, we either have an error code, or an intermmediate
        // reply requesting password.
        if (!FTPReply.isPositiveIntermediate(_replyCode)) {
            return false;
        }

        pass(password);

        if (FTPReply.isPositiveCompletion(_replyCode)) {
            return true;
        }

        if (!FTPReply.isPositiveIntermediate(_replyCode)) {
            return false;
        }

        return FTPReply.isPositiveCompletion(acct(account));
    }

    /**
     * Logout of the FTP server by sending the QUIT command.
     *
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean logout() throws IOException
    {
        return FTPReply.isPositiveCompletion(quit());
    }


    /**
     * Change the current working directory of the FTP session.
     *
     * @param pathname  The new current working directory.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean changeWorkingDirectory(String pathname) throws IOException
    {
        return FTPReply.isPositiveCompletion(cwd(pathname));
    }


    /**
     * Change to the parent directory of the current working directory.
     *
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean changeToParentDirectory() throws IOException
    {
        return FTPReply.isPositiveCompletion(cdup());
    }


    /**
     * Issue the FTP SMNT command.
     *
     * @param pathname The pathname to mount.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean structureMount(String pathname) throws IOException
    {
        return FTPReply.isPositiveCompletion(smnt(pathname));
    }

    /**
     * Reinitialize the FTP session.  Not all FTP servers support this
     * command, which issues the FTP REIN command.
     *
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     * @since 3.4 (made public)
     */
    public boolean reinitialize() throws IOException
    {
        rein();

        if (FTPReply.isPositiveCompletion(_replyCode) ||
                (FTPReply.isPositivePreliminary(_replyCode) &&
                        FTPReply.isPositiveCompletion(getReply())))
        {

            __initDefaults();

            return true;
        }

        return false;
    }


    /**
     * Set the current data connection mode to
     * <code>ACTIVE_LOCAL_DATA_CONNECTION_MODE</code>.  No communication
     * with the FTP server is conducted, but this causes all future data
     * transfers to require the FTP server to connect to the client's
     * data port.  Additionally, to accommodate differences between socket
     * implementations on different platforms, this method causes the
     * client to issue a PORT command before every data transfer.
     */
    public void enterLocalActiveMode()
    {
        __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
        __passiveHost = null;
        __passivePort = -1;
    }


    /**
     * Set the current data connection mode to
     * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code>.  Use this
     * method only for data transfers between the client and server.
     * This method causes a PASV (or EPSV) command to be issued to the server
     * before the opening of every data connection, telling the server to
     * open a data port to which the client will connect to conduct
     * data transfers.  The FTPClient will stay in
     * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code> until the
     * mode is changed by calling some other method such as
     * {@link #enterLocalActiveMode  enterLocalActiveMode() }
     * <p>
     * <b>N.B.</b> currently calling any connect method will reset the mode to
     * ACTIVE_LOCAL_DATA_CONNECTION_MODE.
     */
    public void enterLocalPassiveMode()
    {
        __dataConnectionMode = PASSIVE_LOCAL_DATA_CONNECTION_MODE;
        // These will be set when just before a data connection is opened
        // in _openDataConnection_()
        __passiveHost = null;
        __passivePort = -1;
    }


    /**
     * Set the current data connection mode to
     * <code> ACTIVE_REMOTE_DATA_CONNECTION </code>.  Use this method only
     * for server to server data transfers.  This method issues a PORT
     * command to the server, indicating the other server and port to which
     * it should connect for data transfers.  You must call this method
     * before EVERY server to server transfer attempt.  The FTPClient will
     * NOT automatically continue to issue PORT commands.  You also
     * must remember to call
     * {@link #enterLocalActiveMode  enterLocalActiveMode() } if you
     * wish to return to the normal data connection mode.
     *
     * @param host The passive mode server accepting connections for data
     *             transfers.
     * @param port The passive mode server's data port.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean enterRemoteActiveMode(InetAddress host, int port)
    throws IOException
    {
        if (FTPReply.isPositiveCompletion(port(host, port)))
        {
            __dataConnectionMode = ACTIVE_REMOTE_DATA_CONNECTION_MODE;
            __passiveHost = null;
            __passivePort = -1;
            return true;
        }
        return false;
    }

    /**
     * Set the current data connection mode to
     * <code> PASSIVE_REMOTE_DATA_CONNECTION_MODE </code>.  Use this
     * method only for server to server data transfers.
     * This method issues a PASV command to the server, telling it to
     * open a data port to which the active server will connect to conduct
     * data transfers.  You must call this method
     * before EVERY server to server transfer attempt.  The FTPClient will
     * NOT automatically continue to issue PASV commands.  You also
     * must remember to call
     * {@link #enterLocalActiveMode  enterLocalActiveMode() } if you
     * wish to return to the normal data connection mode.
     *
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean enterRemotePassiveMode() throws IOException
    {
        if (pasv() != FTPReply.ENTERING_PASSIVE_MODE) {
            return false;
        }

        __dataConnectionMode = PASSIVE_REMOTE_DATA_CONNECTION_MODE;
        _parsePassiveModeReply(_replyLines.get(0));

        return true;
    }

    /**
     * Returns the hostname or IP address (in the form of a string) returned
     * by the server when entering passive mode.  If not in passive mode,
     * returns null.  This method only returns a valid value AFTER a
     * data connection has been opened after a call to
     * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
     * This is because FTPClient sends a PASV command to the server only
     * just before opening a data connection, and not when you call
     * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
     *
     * @return The passive host name if in passive mode, otherwise null.
     */
    public String getPassiveHost()
    {
        return __passiveHost;
    }

    /**
     * If in passive mode, returns the data port of the passive host.
     * This method only returns a valid value AFTER a
     * data connection has been opened after a call to
     * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
     * This is because FTPClient sends a PASV command to the server only
     * just before opening a data connection, and not when you call
     * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
     *
     * @return The data port of the passive server.  If not in passive
     *         mode, undefined.
     */
    public int getPassivePort()
    {
        return __passivePort;
    }


    /**
     * Returns the current data connection mode (one of the
     * <code> _DATA_CONNECTION_MODE </code> constants.
     *
     * @return The current data connection mode (one of the
     * <code> _DATA_CONNECTION_MODE </code> constants.
     */
    public int getDataConnectionMode()
    {
        return __dataConnectionMode;
    }

    /**
     * Get the client port for active mode.
     *
     * @return The client port for active mode.
     */
    private int getActivePort()
    {
        if (__activeMinPort > 0 && __activeMaxPort >= __activeMinPort)
        {
            if (__activeMaxPort == __activeMinPort) {
                return __activeMaxPort;
            }
            // Get a random port between the min and max port range
            return __random.nextInt(__activeMaxPort - __activeMinPort + 1) + __activeMinPort;
        }
        else
        {
            // default port
            return 0;
        }
    }

    /**
     * Get the host address for active mode; allows the local address to be overridden.
     *
     * @return __activeExternalHost if non-null, else getLocalAddress()
     * @see #setActiveExternalIPAddress(String)
     */
    private InetAddress getHostAddress()
    {
        if (__activeExternalHost != null)
        {
            return __activeExternalHost;
        }
        else
        {
            // default local address
            return getLocalAddress();
        }
    }

    /**
     * Get the reported host address for active mode EPRT/PORT commands;
     * allows override of {@link #getHostAddress()}.
     *
     * Useful for FTP Client behind Firewall NAT.
     *
     * @return __reportActiveExternalHost if non-null, else getHostAddress();
     */
    private InetAddress getReportHostAddress() {
        if (__reportActiveExternalHost != null) {
            return __reportActiveExternalHost ;
        } else {
            return getHostAddress();
        }
    }

    /**
     * Set the client side port range in active mode.
     *
     * @param minPort The lowest available port (inclusive).
     * @param maxPort The highest available port (inclusive).
     * @since 2.2
     */
    public void setActivePortRange(int minPort, int maxPort)
    {
        this.__activeMinPort = minPort;
        this.__activeMaxPort = maxPort;
    }

    /**
     * Set the external IP address in active mode.
     * Useful when there are multiple network cards.
     *
     * @param ipAddress The external IP address of this machine.
     * @throws UnknownHostException if the ipAddress cannot be resolved
     * @since 2.2
     */
    public void setActiveExternalIPAddress(String ipAddress) throws UnknownHostException
    {
        this.__activeExternalHost = InetAddress.getByName(ipAddress);
    }

    /**
     * Set the local IP address to use in passive mode.
     * Useful when there are multiple network cards.
     *
     * @param ipAddress The local IP address of this machine.
     * @throws UnknownHostException if the ipAddress cannot be resolved
     */
    public void setPassiveLocalIPAddress(String ipAddress) throws UnknownHostException
    {
        this.__passiveLocalHost = InetAddress.getByName(ipAddress);
    }

    /**
     * Set the local IP address to use in passive mode.
     * Useful when there are multiple network cards.
     *
     * @param inetAddress The local IP address of this machine.
     */
    public void setPassiveLocalIPAddress(InetAddress inetAddress)
    {
        this.__passiveLocalHost = inetAddress;
    }

    /**
     * Set the local IP address in passive mode.
     * Useful when there are multiple network cards.
     *
     * @return The local IP address in passive mode.
     */
    public InetAddress getPassiveLocalIPAddress()
    {
        return this.__passiveLocalHost;
    }

    /**
     * Set the external IP address to report in EPRT/PORT commands in active mode.
     * Useful when there are multiple network cards.
     *
     * @param ipAddress The external IP address of this machine.
     * @throws UnknownHostException if the ipAddress cannot be resolved
     * @since 3.1
     * @see #getReportHostAddress()
     */
    public void setReportActiveExternalIPAddress(String ipAddress) throws UnknownHostException
    {
        this.__reportActiveExternalHost = InetAddress.getByName(ipAddress);
    }


    /**
     * Sets the file type to be transferred.  This should be one of
     * <code> FTP.ASCII_FILE_TYPE </code>, <code> FTP.BINARY_FILE_TYPE</code>,
     * etc.  The file type only needs to be set when you want to change the
     * type.  After changing it, the new type stays in effect until you change
     * it again.  The default file type is <code> FTP.ASCII_FILE_TYPE </code>
     * if this method is never called.
     * <br>
     * The server default is supposed to be ASCII (see RFC 959), however many
     * ftp servers default to BINARY. <b>To ensure correct operation with all servers,
     * always specify the appropriate file type after connecting to the server.</b>
     * <br>
     * <p>
     * <b>N.B.</b> currently calling any connect method will reset the type to
     * FTP.ASCII_FILE_TYPE.
     * @param fileType The <code> _FILE_TYPE </code> constant indicating the
     *                 type of file.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean setFileType(int fileType) throws IOException
    {
        if (FTPReply.isPositiveCompletion(type(fileType)))
        {
            __fileType = fileType;
            __fileFormat = FTP.NON_PRINT_TEXT_FORMAT;
            return true;
        }
        return false;
    }


    /**
     * Sets the file type to be transferred and the format.  The type should be
     * one of  <code> FTP.ASCII_FILE_TYPE </code>,
     * <code> FTP.BINARY_FILE_TYPE </code>, etc.  The file type only needs to
     * be set when you want to change the type.  After changing it, the new
     * type stays in effect until you change it again.  The default file type
     * is <code> FTP.ASCII_FILE_TYPE </code> if this method is never called.
     * <br>
     * The server default is supposed to be ASCII (see RFC 959), however many
     * ftp servers default to BINARY. <b>To ensure correct operation with all servers,
     * always specify the appropriate file type after connecting to the server.</b>
     * <br>
     * The format should be one of the FTP class <code> TEXT_FORMAT </code>
     * constants, or if the type is <code> FTP.LOCAL_FILE_TYPE </code>, the
     * format should be the byte size for that type.  The default format
     * is <code> FTP.NON_PRINT_TEXT_FORMAT </code> if this method is never
     * called.
     * <p>
     * <b>N.B.</b> currently calling any connect method will reset the type to
     * FTP.ASCII_FILE_TYPE and the formatOrByteSize to FTP.NON_PRINT_TEXT_FORMAT.
     *
     * @param fileType The <code> _FILE_TYPE </code> constant indicating the
     *                 type of file.
     * @param formatOrByteSize  The format of the file (one of the
     *              <code>_FORMAT</code> constants.  In the case of
     *              <code>LOCAL_FILE_TYPE</code>, the byte size.
     *
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean setFileType(int fileType, int formatOrByteSize)
    throws IOException
    {
        if (FTPReply.isPositiveCompletion(type(fileType, formatOrByteSize)))
        {
            __fileType = fileType;
            __fileFormat = formatOrByteSize;
            return true;
        }
        return false;
    }


    /**
     * Sets the file structure.  The default structure is
     * <code> FTP.FILE_STRUCTURE </code> if this method is never called
     * or if a connect method is called.
     *
     * @param structure  The structure of the file (one of the FTP class
     *         <code>_STRUCTURE</code> constants).
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean setFileStructure(int structure) throws IOException
    {
        if (FTPReply.isPositiveCompletion(stru(structure)))
        {
            __fileStructure = structure;
            return true;
        }
        return false;
    }


    /**
     * Sets the transfer mode.  The default transfer mode
     * <code> FTP.STREAM_TRANSFER_MODE </code> if this method is never called
     * or if a connect method is called.
     *
     * @param mode  The new transfer mode to use (one of the FTP class
     *         <code>_TRANSFER_MODE</code> constants).
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean setFileTransferMode(int mode) throws IOException
    {
        if (FTPReply.isPositiveCompletion(mode(mode)))
        {
            __fileTransferMode = mode;
            return true;
        }
        return false;
    }


    /**
     * Initiate a server to server file transfer.  This method tells the
     * server to which the client is connected to retrieve a given file from
     * the other server.
     *
     * @param filename  The name of the file to retrieve.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean remoteRetrieve(String filename) throws IOException
    {
        if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
                __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE) {
            return FTPReply.isPositivePreliminary(retr(filename));
        }
        return false;
    }


    /**
     * Initiate a server to server file transfer.  This method tells the
     * server to which the client is connected to store a file on
     * the other server using the given filename.  The other server must
     * have had a <code> remoteRetrieve </code> issued to it by another
     * FTPClient.
     *
     * @param filename  The name to call the file that is to be stored.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean remoteStore(String filename) throws IOException
    {
        if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
                __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE) {
            return FTPReply.isPositivePreliminary(stor(filename));
        }
        return false;
    }


    /**
     * Initiate a server to server file transfer.  This method tells the
     * server to which the client is connected to store a file on
     * the other server using a unique filename based on the given filename.
     * The other server must have had a <code> remoteRetrieve </code> issued
     * to it by another FTPClient.
     *
     * @param filename  The name on which to base the filename of the file
     *                  that is to be stored.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean remoteStoreUnique(String filename) throws IOException
    {
        if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
                __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE) {
            return FTPReply.isPositivePreliminary(stou(filename));
        }
        return false;
    }


    /**
     * Initiate a server to server file transfer.  This method tells the
     * server to which the client is connected to store a file on
     * the other server using a unique filename.
     * The other server must have had a <code> remoteRetrieve </code> issued
     * to it by another FTPClient.  Many FTP servers require that a base
     * filename be given from which the unique filename can be derived.  For
     * those servers use the other version of <code> remoteStoreUnique</code>
     *
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean remoteStoreUnique() throws IOException
    {
        if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
                __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE) {
            return FTPReply.isPositivePreliminary(stou());
        }
        return false;
    }

    // For server to server transfers
    /**
     * Initiate a server to server file transfer.  This method tells the
     * server to which the client is connected to append to a given file on
     * the other server.  The other server must have had a
     * <code> remoteRetrieve </code> issued to it by another FTPClient.
     *
     * @param filename  The name of the file to be appended to, or if the
     *        file does not exist, the name to call the file being stored.
     *
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean remoteAppend(String filename) throws IOException
    {
        if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
                __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE) {
            return FTPReply.isPositivePreliminary(appe(filename));
        }
        return false;
    }

    /**
     * There are a few FTPClient methods that do not complete the
     * entire sequence of FTP commands to complete a transaction.  These
     * commands require some action by the programmer after the reception
     * of a positive intermediate command.  After the programmer's code
     * completes its actions, it must call this method to receive
     * the completion reply from the server and verify the success of the
     * entire transaction.
     * <p>
     * For example,
     * <pre>
     * InputStream input;
     * OutputStream output;
     * input  = new FileInputStream("foobaz.txt");
     * output = ftp.storeFileStream("foobar.txt")
     * if(!FTPReply.isPositiveIntermediate(ftp.getReplyCode())) {
     *     input.close();
     *     output.close();
     *     ftp.logout();
     *     ftp.disconnect();
     *     System.err.println("File transfer failed.");
     *     System.exit(1);
     * }
     * Util.copyStream(input, output);
     * input.close();
     * output.close();
     * // Must call completePendingCommand() to finish command.
     * if(!ftp.completePendingCommand()) {
     *     ftp.logout();
     *     ftp.disconnect();
     *     System.err.println("File transfer failed.");
     *     System.exit(1);
     * }
     * </pre>
     *
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean completePendingCommand() throws IOException
    {
        return FTPReply.isPositiveCompletion(getReply());
    }


    /**
     * Retrieves a named file from the server and writes it to the given
     * OutputStream.  This method does NOT close the given OutputStream.
     * If the current file type is ASCII, line separators in the file are
     * converted to the local representation.
     * <p>
     * Note: if you have used {@link #setRestartOffset(long)},
     * the file data will start from the selected offset.
     * @param remote  The name of the remote file.
     * @param local   The local OutputStream to which to write the file.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws org.apache.commons.net.io.CopyStreamException
     *      If an I/O error occurs while actually
     *      transferring the file.  The CopyStreamException allows you to
     *      determine the number of bytes transferred and the IOException
     *      causing the error.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean retrieveFile(String remote, OutputStream local)
    throws IOException
    {
        return _retrieveFile(FTPCmd.RETR.getCommand(), remote, local);
    }

    /**
     * @param command the command to get
     * @param remote the remote file name
     * @param local The local OutputStream to which to write the file.
     * @return true if successful
     * @throws IOException on error
     * @since 3.1
     */
    protected boolean _retrieveFile(String command, String remote, OutputStream local)
    throws IOException
    {
        Socket socket = _openDataConnection_(command, remote);

        if (socket == null) {
            return false;
        }

        final InputStream input;
        if (__fileType == ASCII_FILE_TYPE) {
            input = new FromNetASCIIInputStream(getBufferedInputStream(socket.getInputStream()));
        } else {
            input = getBufferedInputStream(socket.getInputStream());
        }

        CSL csl = null;
        if (__controlKeepAliveTimeout > 0) {
            csl = new CSL(this, __controlKeepAliveTimeout, __controlKeepAliveReplyTimeout);
        }

        // Treat everything else as binary for now
        try
        {
            Util.copyStream(input, local, getBufferSize(),
                    CopyStreamEvent.UNKNOWN_STREAM_SIZE, __mergeListeners(csl),
                    false);

            // Get the transfer response
            return completePendingCommand();
        } finally {
            Util.closeQuietly(input);
            Util.closeQuietly(socket);
            if (csl != null) {
                __cslDebug = csl.cleanUp(); // fetch any outstanding keepalive replies
            }
        }
    }

    /**
     * Returns an InputStream from which a named file from the server
     * can be read.  If the current file type is ASCII, the returned
     * InputStream will convert line separators in the file to
     * the local representation.  You must close the InputStream when you
     * finish reading from it.  The InputStream itself will take care of
     * closing the parent data connection socket upon being closed.
     * <p>
     * <b>To finalize the file transfer you must call
     * {@link #completePendingCommand  completePendingCommand } and
     * check its return value to verify success.</b>
     * If this is not done, subsequent commands may behave unexpectedly.
     * <p>
     * Note: if you have used {@link #setRestartOffset(long)},
     * the file data will start from the selected offset.
     *
     * @param remote  The name of the remote file.
     * @return An InputStream from which the remote file can be read.  If
     *      the data connection cannot be opened (e.g., the file does not
     *      exist), null is returned (in which case you may check the reply
     *      code to determine the exact reason for failure).
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public InputStream retrieveFileStream(String remote) throws IOException
    {
        return _retrieveFileStream(FTPCmd.RETR.getCommand(), remote);
    }

    /**
     * @param command the command to send
     * @param remote the remote file name
     * @return the stream from which to read the file
     * @throws IOException on error
     * @since 3.1
     */
    protected InputStream _retrieveFileStream(String command, String remote)
    throws IOException
    {
        Socket socket = _openDataConnection_(command, remote);

        if (socket == null) {
            return null;
        }

        final InputStream input;
        if (__fileType == ASCII_FILE_TYPE) {
            // We buffer ascii transfers because the buffering has to
            // be interposed between FromNetASCIIOutputSream and the underlying
            // socket input stream.  We don't buffer binary transfers
            // because we don't want to impose a buffering policy on the
            // programmer if possible.  Programmers can decide on their
            // own if they want to wrap the SocketInputStream we return
            // for file types other than ASCII.
            input = new FromNetASCIIInputStream(getBufferedInputStream(socket.getInputStream()));
        } else {
            input = socket.getInputStream();
        }
        return new org.apache.commons.net.io.SocketInputStream(socket, input);
    }


    /**
     * Stores a file on the server using the given name and taking input
     * from the given InputStream.  This method does NOT close the given
     * InputStream.  If the current file type is ASCII, line separators in
     * the file are transparently converted to the NETASCII format (i.e.,
     * you should not attempt to create a special InputStream to do this).
     *
     * @param remote  The name to give the remote file.
     * @param local   The local InputStream from which to read the file.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws org.apache.commons.net.io.CopyStreamException
     *      If an I/O error occurs while actually
     *      transferring the file.  The CopyStreamException allows you to
     *      determine the number of bytes transferred and the IOException
     *      causing the error.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean storeFile(String remote, InputStream local)
    throws IOException
    {
        return __storeFile(FTPCmd.STOR, remote, local);
    }


    /**
     * Returns an OutputStream through which data can be written to store
     * a file on the server using the given name.  If the current file type
     * is ASCII, the returned OutputStream will convert line separators in
     * the file to the NETASCII format  (i.e., you should not attempt to
     * create a special OutputStream to do this).  You must close the
     * OutputStream when you finish writing to it.  The OutputStream itself
     * will take care of closing the parent data connection socket upon being
     * closed.
     * <p>
     * <b>To finalize the file transfer you must call
     * {@link #completePendingCommand  completePendingCommand } and
     * check its return value to verify success.</b>
     * If this is not done, subsequent commands may behave unexpectedly.
     *
     * @param remote  The name to give the remote file.
     * @return An OutputStream through which the remote file can be written.  If
     *      the data connection cannot be opened (e.g., the file does not
     *      exist), null is returned (in which case you may check the reply
     *      code to determine the exact reason for failure).
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public OutputStream storeFileStream(String remote) throws IOException
    {
        return __storeFileStream(FTPCmd.STOR, remote);
    }

    /**
     * Appends to a file on the server with the given name, taking input
     * from the given InputStream.  This method does NOT close the given
     * InputStream.  If the current file type is ASCII, line separators in
     * the file are transparently converted to the NETASCII format (i.e.,
     * you should not attempt to create a special InputStream to do this).
     *
     * @param remote  The name of the remote file.
     * @param local   The local InputStream from which to read the data to
     *                be appended to the remote file.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws org.apache.commons.net.io.CopyStreamException
     *      If an I/O error occurs while actually
     *      transferring the file.  The CopyStreamException allows you to
     *      determine the number of bytes transferred and the IOException
     *      causing the error.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean appendFile(String remote, InputStream local)
    throws IOException
    {
        return __storeFile(FTPCmd.APPE, remote, local);
    }

    /**
     * Returns an OutputStream through which data can be written to append
     * to a file on the server with the given name.  If the current file type
     * is ASCII, the returned OutputStream will convert line separators in
     * the file to the NETASCII format  (i.e., you should not attempt to
     * create a special OutputStream to do this).  You must close the
     * OutputStream when you finish writing to it.  The OutputStream itself
     * will take care of closing the parent data connection socket upon being
     * closed.
     * <p>
     * <b>To finalize the file transfer you must call
     * {@link #completePendingCommand  completePendingCommand } and
     * check its return value to verify success.</b>
     * If this is not done, subsequent commands may behave unexpectedly.
     *
     * @param remote  The name of the remote file.
     * @return An OutputStream through which the remote file can be appended.
     *      If the data connection cannot be opened (e.g., the file does not
     *      exist), null is returned (in which case you may check the reply
     *      code to determine the exact reason for failure).
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public OutputStream appendFileStream(String remote) throws IOException
    {
        return __storeFileStream(FTPCmd.APPE, remote);
    }

    /**
     * Stores a file on the server using a unique name derived from the
     * given name and taking input
     * from the given InputStream.  This method does NOT close the given
     * InputStream.  If the current file type is ASCII, line separators in
     * the file are transparently converted to the NETASCII format (i.e.,
     * you should not attempt to create a special InputStream to do this).
     *
     * @param remote  The name on which to base the unique name given to
     *                the remote file.
     * @param local   The local InputStream from which to read the file.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws org.apache.commons.net.io.CopyStreamException
     *      If an I/O error occurs while actually
     *      transferring the file.  The CopyStreamException allows you to
     *      determine the number of bytes transferred and the IOException
     *      causing the error.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean storeUniqueFile(String remote, InputStream local)
    throws IOException
    {
        return __storeFile(FTPCmd.STOU, remote, local);
    }


    /**
     * Returns an OutputStream through which data can be written to store
     * a file on the server using a unique name derived from the given name.
     * If the current file type
     * is ASCII, the returned OutputStream will convert line separators in
     * the file to the NETASCII format  (i.e., you should not attempt to
     * create a special OutputStream to do this).  You must close the
     * OutputStream when you finish writing to it.  The OutputStream itself
     * will take care of closing the parent data connection socket upon being
     * closed.
     * <p>
     * <b>To finalize the file transfer you must call
     * {@link #completePendingCommand  completePendingCommand } and
     * check its return value to verify success.</b>
     * If this is not done, subsequent commands may behave unexpectedly.
     *
     * @param remote  The name on which to base the unique name given to
     *                the remote file.
     * @return An OutputStream through which the remote file can be written.  If
     *      the data connection cannot be opened (e.g., the file does not
     *      exist), null is returned (in which case you may check the reply
     *      code to determine the exact reason for failure).
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public OutputStream storeUniqueFileStream(String remote) throws IOException
    {
        return __storeFileStream(FTPCmd.STOU, remote);
    }

    /**
     * Stores a file on the server using a unique name assigned by the
     * server and taking input from the given InputStream.  This method does
     * NOT close the given
     * InputStream.  If the current file type is ASCII, line separators in
     * the file are transparently converted to the NETASCII format (i.e.,
     * you should not attempt to create a special InputStream to do this).
     *
     * @param local   The local InputStream from which to read the file.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws org.apache.commons.net.io.CopyStreamException
     *      If an I/O error occurs while actually
     *      transferring the file.  The CopyStreamException allows you to
     *      determine the number of bytes transferred and the IOException
     *      causing the error.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean storeUniqueFile(InputStream local) throws IOException
    {
        return __storeFile(FTPCmd.STOU, null, local);
    }

    /**
     * Returns an OutputStream through which data can be written to store
     * a file on the server using a unique name assigned by the server.
     * If the current file type
     * is ASCII, the returned OutputStream will convert line separators in
     * the file to the NETASCII format  (i.e., you should not attempt to
     * create a special OutputStream to do this).  You must close the
     * OutputStream when you finish writing to it.  The OutputStream itself
     * will take care of closing the parent data connection socket upon being
     * closed.
     * <p>
     * <b>To finalize the file transfer you must call
     * {@link #completePendingCommand  completePendingCommand } and
     * check its return value to verify success.</b>
     * If this is not done, subsequent commands may behave unexpectedly.
     *
     * @return An OutputStream through which the remote file can be written.  If
     *      the data connection cannot be opened (e.g., the file does not
     *      exist), null is returned (in which case you may check the reply
     *      code to determine the exact reason for failure).
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public OutputStream storeUniqueFileStream() throws IOException
    {
        return __storeFileStream(FTPCmd.STOU, null);
    }

    /**
     * Reserve a number of bytes on the server for the next file transfer.
     *
     * @param bytes  The number of bytes which the server should allocate.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean allocate(int bytes) throws IOException
    {
        return FTPReply.isPositiveCompletion(allo(bytes));
    }

    /**
     * Query the server for supported features. The server may reply with a list of server-supported exensions.
     * For example, a typical client-server interaction might be (from RFC 2389):
     * <pre>
        C&gt; feat
        S&gt; 211-Extensions supported:
        S&gt;  MLST size*;create;modify*;perm;media-type
        S&gt;  SIZE
        S&gt;  COMPRESSION
        S&gt;  MDTM
        S&gt; 211 END
     * </pre>
     * @see <a href="http://www.faqs.org/rfcs/rfc2389.html">http://www.faqs.org/rfcs/rfc2389.html</a>
     * @return True if successfully completed, false if not.
     * @throws IOException on error
     * @since 2.2
     */
    public boolean features() throws IOException {
        return FTPReply.isPositiveCompletion(feat());
    }

    /**
     * Query the server for a supported feature, and returns its values (if any).
     * Caches the parsed response to avoid resending the command repeatedly.
     * @param feature the feature to check
     *
     * @return if the feature is present, returns the feature values (empty array if none)
     * Returns {@code null} if the feature is not found or the command failed.
     * Check {@link #getReplyCode()} or {@link #getReplyString()} if so.
     * @throws IOException on error
     * @since 3.0
     */
    public String[] featureValues(String feature) throws IOException {
        if (!initFeatureMap()) {
            return null;
        }
        Set<String> entries = __featuresMap.get(feature.toUpperCase(Locale.ENGLISH));
        if (entries != null) {
            return entries.toArray(new String[entries.size()]);
        }
        return null;
    }

    /**
     * Query the server for a supported feature, and returns the its value (if any).
     * Caches the parsed response to avoid resending the command repeatedly.
     * @param feature the feature to check
     *
     * @return if the feature is present, returns the feature value or the empty string
     * if the feature exists but has no value.
     * Returns {@code null} if the feature is not found or the command failed.
     * Check {@link #getReplyCode()} or {@link #getReplyString()} if so.
     * @throws IOException on error
     * @since 3.0
     */
    public String featureValue(String feature) throws IOException {
        String [] values = featureValues(feature);
        if (values != null) {
            return values[0];
        }
        return null;
    }

    /**
     * Query the server for a supported feature.
     * Caches the parsed response to avoid resending the command repeatedly.
     *
     * @param feature the name of the feature; it is converted to upper case.
     * @return {@code true} if the feature is present, {@code false} if the feature is not present
     * or the {@link #feat()} command failed. Check {@link #getReplyCode()} or {@link #getReplyString()}
     * if it is necessary to distinguish these cases.
     *
     * @throws IOException on error
     * @since 3.0
     */
    public boolean hasFeature(String feature) throws IOException {
        if (!initFeatureMap()) {
            return false;
        }
        return __featuresMap.containsKey(feature.toUpperCase(Locale.ENGLISH));
    }

    /**
     * Query the server for a supported feature with particular value,
     * for example "AUTH SSL" or "AUTH TLS".
     * Caches the parsed response to avoid resending the command repeatedly.
     *
     * @param feature the name of the feature; it is converted to upper case.
     * @param value the value to find.
     *
     * @return {@code true} if the feature is present, {@code false} if the feature is not present
     * or the {@link #feat()} command failed. Check {@link #getReplyCode()} or {@link #getReplyString()}
     * if it is necessary to distinguish these cases.
     *
     * @throws IOException on error
     * @since 3.0
     */
    public boolean hasFeature(String feature, String value) throws IOException {
        if (!initFeatureMap()) {
            return false;
        }
        Set<String> entries = __featuresMap.get(feature.toUpperCase(Locale.ENGLISH));
        if (entries != null) {
            return entries.contains(value);
        }
        return false;
    }

    /*
     * Create the feature map if not already created.
     */
    private boolean initFeatureMap() throws IOException {
        if (__featuresMap == null) {
            // Don't create map here, because next line may throw exception
            final int replyCode = feat();
            if (replyCode == FTPReply.NOT_LOGGED_IN) { // 503
                return false; // NET-518; don't create empy map
            }
            boolean success = FTPReply.isPositiveCompletion(replyCode);
            // we init the map here, so we don't keep trying if we know the command will fail
            __featuresMap = new HashMap<String, Set<String>>();
            if (!success) {
                return false;
            }
            for (String l : getReplyStrings()) {
                if (l.startsWith(" ")) { // it's a FEAT entry
                    String key;
                    String value="";
                    int varsep = l.indexOf(' ', 1);
                    if (varsep > 0) {
                        key = l.substring(1, varsep);
                        value = l.substring(varsep+1);
                    } else {
                        key = l.substring(1);
                    }
                    key = key.toUpperCase(Locale.ENGLISH);
                    Set<String> entries = __featuresMap.get(key);
                    if (entries == null) {
                        entries = new HashSet<String>();
                        __featuresMap.put(key, entries);
                    }
                    entries.add(value);
                }
            }
        }
        return true;
    }

    /**
     * Reserve space on the server for the next file transfer.
     *
     * @param bytes  The number of bytes which the server should allocate.
     * @param recordSize  The size of a file record.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean allocate(int bytes, int recordSize) throws IOException
    {
        return FTPReply.isPositiveCompletion(allo(bytes, recordSize));
    }


    /**
     * Issue a command and wait for the reply.
     * <p>
     * Should only be used with commands that return replies on the
     * command channel - do not use for LIST, NLST, MLSD etc.
     *
     * @param command  The command to invoke
     * @param params  The parameters string, may be {@code null}
     * @return True if successfully completed, false if not, in which case
     * call {@link #getReplyCode()} or {@link #getReplyString()}
     * to get the reason.
     *
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     * @since 3.0
     */
    public boolean doCommand(String command, String params) throws IOException
    {
        return FTPReply.isPositiveCompletion(sendCommand(command, params));
    }

    /**
     * Issue a command and wait for the reply, returning it as an array of strings.
     * <p>
     * Should only be used with commands that return replies on the
     * command channel - do not use for LIST, NLST, MLSD etc.
     *
     * @param command  The command to invoke
     * @param params  The parameters string, may be {@code null}
     * @return The array of replies, or {@code null} if the command failed, in which case
     * call {@link #getReplyCode()} or {@link #getReplyString()}
     * to get the reason.
     *
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     * @since 3.0
     */
    public String[] doCommandAsStrings(String command, String params) throws IOException
    {
        boolean success = FTPReply.isPositiveCompletion(sendCommand(command, params));
        if (success){
            return getReplyStrings();
        } else {
            return null;
        }
    }

    /**
     * Get file details using the MLST command
     *
     * @param pathname the file or directory to list, may be {@code null}
     * @return the file details, may be {@code null}
     * @throws IOException on error
     * @since 3.0
     */
    public FTPFile mlistFile(String pathname) throws IOException
    {
        boolean success = FTPReply.isPositiveCompletion(sendCommand(FTPCmd.MLST, pathname));
        if (success){
            String reply = getReplyStrings()[1];
            /* check the response makes sense.
             * Must have space before fact(s) and between fact(s) and filename
             * Fact(s) can be absent, so at least 3 chars are needed.
             */
            if (reply.length() < 3 || reply.charAt(0) != ' ') {
                throw new MalformedServerReplyException("Invalid server reply (MLST): '" + reply + "'");
            }
            String entry = reply.substring(1); // skip leading space for parser
            return MLSxEntryParser.parseEntry(entry);
        } else {
            return null;
        }
    }

    /**
     * Generate a directory listing for the current directory using the MLSD command.
     *
     * @return the array of file entries
     * @throws IOException on error
     * @since 3.0
     */
    public FTPFile[] mlistDir() throws IOException
    {
        return mlistDir(null);
    }

    /**
     * Generate a directory listing using the MLSD command.
     *
     * @param pathname the directory name, may be {@code null}
     * @return the array of file entries
     * @throws IOException on error
     * @since 3.0
     */
    public FTPFile[] mlistDir(String pathname) throws IOException
    {
        FTPListParseEngine engine = initiateMListParsing( pathname);
        return engine.getFiles();
    }

    /**
     * Generate a directory listing using the MLSD command.
     *
     * @param pathname the directory name, may be {@code null}
     * @param filter the filter to apply to the responses
     * @return the array of file entries
     * @throws IOException on error
     * @since 3.0
     */
    public FTPFile[] mlistDir(String pathname, FTPFileFilter filter) throws IOException
    {
        FTPListParseEngine engine = initiateMListParsing( pathname);
        return engine.getFiles(filter);
    }

    /**
     * Restart a <code>STREAM_TRANSFER_MODE</code> file transfer starting
     * from the given offset.  This will only work on FTP servers supporting
     * the REST comand for the stream transfer mode.  However, most FTP
     * servers support this.  Any subsequent file transfer will start
     * reading or writing the remote file from the indicated offset.
     *
     * @param offset  The offset into the remote file at which to start the
     *           next file transfer.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     * @since 3.1 (changed from private to protected)
     */
    protected boolean restart(long offset) throws IOException
    {
        __restartOffset = 0;
        return FTPReply.isPositiveIntermediate(rest(Long.toString(offset)));
    }

    /**
     * Sets the restart offset for file transfers.
     * <p>
     * The restart command is not sent to the server immediately.
     * It is sent when a data connection is created as part of a
     * subsequent command.
     * The restart marker is reset to zero after use.
     * </p>
     * <p>
     * <b>Note: This method should only be invoked immediately prior to
     * the transfer to which it applies.</b>
     *
     * @param offset  The offset into the remote file at which to start the
     *           next file transfer.  This must be a value greater than or
     *           equal to zero.
     */
    public void setRestartOffset(long offset)
    {
        if (offset >= 0) {
            __restartOffset = offset;
        }
    }

    /**
     * Fetches the restart offset.
     *
     * @return offset  The offset into the remote file at which to start the
     *           next file transfer.
     */
    public long getRestartOffset()
    {
        return __restartOffset;
    }



    /**
     * Renames a remote file.
     *
     * @param from  The name of the remote file to rename.
     * @param to    The new name of the remote file.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean rename(String from, String to) throws IOException
    {
        if (!FTPReply.isPositiveIntermediate(rnfr(from))) {
            return false;
        }

        return FTPReply.isPositiveCompletion(rnto(to));
    }


    /**
     * Abort a transfer in progress.
     *
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean abort() throws IOException
    {
        return FTPReply.isPositiveCompletion(abor());
    }

    /**
     * Deletes a file on the FTP server.
     *
     * @param pathname   The pathname of the file to be deleted.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean deleteFile(String pathname) throws IOException
    {
        return FTPReply.isPositiveCompletion(dele(pathname));
    }


    /**
     * Removes a directory on the FTP server (if empty).
     *
     * @param pathname  The pathname of the directory to remove.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean removeDirectory(String pathname) throws IOException
    {
        return FTPReply.isPositiveCompletion(rmd(pathname));
    }


    /**
     * Creates a new subdirectory on the FTP server in the current directory
     * (if a relative pathname is given) or where specified (if an absolute
     * pathname is given).
     *
     * @param pathname The pathname of the directory to create.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean makeDirectory(String pathname) throws IOException
    {
        return FTPReply.isPositiveCompletion(mkd(pathname));
    }


    /**
     * Returns the pathname of the current working directory.
     *
     * @return The pathname of the current working directory.  If it cannot
     *         be obtained, returns null.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public String printWorkingDirectory() throws IOException
    {
        if (pwd() != FTPReply.PATHNAME_CREATED) {
            return null;
        }

        return __parsePathname(_replyLines.get( _replyLines.size() - 1));
    }


    /**
     * Send a site specific command.
     * @param arguments The site specific command and arguments.
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean sendSiteCommand(String arguments) throws IOException
    {
        return FTPReply.isPositiveCompletion(site(arguments));
    }


    /**
     * Fetches the system type from the server and returns the string.
     * This value is cached for the duration of the connection after the
     * first call to this method.  In other words, only the first time
     * that you invoke this method will it issue a SYST command to the
     * FTP server.  FTPClient will remember the value and return the
     * cached value until a call to disconnect.
     * <p>
     * If the SYST command fails, and the system property
     * {@link #FTP_SYSTEM_TYPE_DEFAULT} is defined, then this is used instead.
     * @return The system type obtained from the server. Never null.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *  command to the server or receiving a reply from the server (and the default
     *  system type property is not defined)
     *  @since 2.2
     */
    public String getSystemType() throws IOException
    {
        //if (syst() == FTPReply.NAME_SYSTEM_TYPE)
        // Technically, we should expect a NAME_SYSTEM_TYPE response, but
        // in practice FTP servers deviate, so we soften the condition to
        // a positive completion.
        if (__systemName == null){
            if (FTPReply.isPositiveCompletion(syst())) {
                // Assume that response is not empty here (cannot be null)
                __systemName = _replyLines.get(_replyLines.size() - 1).substring(4);
            } else {
                // Check if the user has provided a default for when the SYST command fails
                String systDefault = System.getProperty(FTP_SYSTEM_TYPE_DEFAULT);
                if (systDefault != null) {
                    __systemName = systDefault;
                } else {
                    throw new IOException("Unable to determine system type - response: " + getReplyString());
                }
            }
        }
        return __systemName;
    }


    /**
     * Fetches the system help information from the server and returns the
     * full string.
     *
     * @return The system help string obtained from the server.  null if the
     *       information could not be obtained.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *  command to the server or receiving a reply from the server.
     */
    public String listHelp() throws IOException
    {
        if (FTPReply.isPositiveCompletion(help())) {
            return getReplyString();
        }
        return null;
    }


    /**
     * Fetches the help information for a given command from the server and
     * returns the full string.
     * @param command The command on which to ask for help.
     * @return The command help string obtained from the server.  null if the
     *       information could not be obtained.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *  command to the server or receiving a reply from the server.
     */
    public String listHelp(String command) throws IOException
    {
        if (FTPReply.isPositiveCompletion(help(command))) {
            return getReplyString();
        }
        return null;
    }


    /**
     * Sends a NOOP command to the FTP server.  This is useful for preventing
     * server timeouts.
     *
     * @return True if successfully completed, false if not.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public boolean sendNoOp() throws IOException
    {
        return FTPReply.isPositiveCompletion(noop());
    }


    /**
     * Obtain a list of filenames in a directory (or just the name of a given
     * file, which is not particularly useful).  This information is obtained
     * through the NLST command.  If the given pathname is a directory and
     * contains no files,  a zero length array is returned only
     * if the FTP server returned a positive completion code, otherwise
     * null is returned (the FTP server returned a 550 error No files found.).
     * If the directory is not empty, an array of filenames in the directory is
     * returned. If the pathname corresponds
     * to a file, only that file will be listed.  The server may or may not
     * expand glob expressions.
     *
     * @param pathname  The file or directory to list.
     *                  Warning: the server may treat a leading '-' as an
     *                  option introducer. If so, try using an absolute path,
     *                  or prefix the path with ./ (unix style servers).
     *                  Some servers may support "--" as meaning end of options,
     *                  in which case "-- -xyz" should work.
     * @return The list of filenames contained in the given path.  null if
     *     the list could not be obtained.  If there are no filenames in
     *     the directory, a zero-length array is returned.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public String[] listNames(String pathname) throws IOException
    {
        Socket socket = _openDataConnection_(FTPCmd.NLST, getListArguments(pathname));

        if (socket == null) {
            return null;
        }

        BufferedReader reader =
            new BufferedReader(new InputStreamReader(socket.getInputStream(), getControlEncoding()));

        ArrayList<String> results = new ArrayList<String>();
        String line;
        while ((line = reader.readLine()) != null) {
            results.add(line);
        }

        reader.close();
        socket.close();

        if (completePendingCommand())
        {
            String[] names = new String[ results.size() ];
            return results.toArray(names);
        }

        return null;
    }


    /**
     * Obtain a list of filenames in the current working directory
     * This information is obtained through the NLST command.  If the current
     * directory contains no files, a zero length array is returned only
     * if the FTP server returned a positive completion code, otherwise,
     * null is returned (the FTP server returned a 550 error No files found.).
     * If the directory is not empty, an array of filenames in the directory is
     * returned.
     *
     * @return The list of filenames contained in the current working
     *     directory.  null if the list could not be obtained.
     *     If there are no filenames in the directory, a zero-length array
     *     is returned.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public String[] listNames() throws IOException
    {
        return listNames(null);
    }



    /**
     * Using the default system autodetect mechanism, obtain a
     * list of file information for the current working directory
     * or for just a single file.
     * <p>
     * This information is obtained through the LIST command.  The contents of
     * the returned array is determined by the<code> FTPFileEntryParser </code>
     * used.
     * <p>
     * N.B. the LIST command does not generally return very precise timestamps.
     * For recent files, the response usually contains hours and minutes (not seconds).
     * For older files, the output may only contain a date.
     * If the server supports it, the MLSD command returns timestamps with a precision
     * of seconds, and may include milliseconds. See {@link #mlistDir()}
     *
     * @param pathname  The file or directory to list.  Since the server may
     *                  or may not expand glob expressions, using them here
     *                  is not recommended and may well cause this method to
     *                  fail.
     *                  Also, some servers treat a leading '-' as being an option.
     *                  To avoid this interpretation, use an absolute pathname
     *                  or prefix the pathname with ./ (unix style servers).
     *                  Some servers may support "--" as meaning end of options,
     *                  in which case "-- -xyz" should work.
     *
     * @return The list of file information contained in the given path in
     *         the format determined by the autodetection mechanism
     * @throws FTPConnectionClosedException
     *                   If the FTP server prematurely closes the connection
     *                   as a result of the client being idle or some other
     *                   reason causing the server to send FTP reply code 421.
     *                   This exception may be caught either as an IOException
     *                   or independently as itself.
     * @throws IOException
     *                   If an I/O error occurs while either sending a
     *                   command to the server or receiving a reply
     *                   from the server.
     * @throws org.apache.commons.net.ftp.parser.ParserInitializationException
     *                   Thrown if the parserKey parameter cannot be
     *                   resolved by the selected parser factory.
     *                   In the DefaultFTPEntryParserFactory, this will
     *                   happen when parserKey is neither
     *                   the fully qualified class name of a class
     *                   implementing the interface
     *                   org.apache.commons.net.ftp.FTPFileEntryParser
     *                   nor a string containing one of the recognized keys
     *                   mapping to such a parser or if class loader
     *                   security issues prevent its being loaded.
     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
     * @see org.apache.commons.net.ftp.FTPFileEntryParser
     */
    public FTPFile[] listFiles(String pathname)
    throws IOException
    {
        FTPListParseEngine engine = initiateListParsing((String) null, pathname);
        return engine.getFiles();

    }

    /**
     * Using the default system autodetect mechanism, obtain a
     * list of file information for the current working directory.
     * <p>
     * This information is obtained through the LIST command.  The contents of
     * the returned array is determined by the<code> FTPFileEntryParser </code>
     * used.
     * <p>
     * N.B. the LIST command does not generally return very precise timestamps.
     * For recent files, the response usually contains hours and minutes (not seconds).
     * For older files, the output may only contain a date.
     * If the server supports it, the MLSD command returns timestamps with a precision
     * of seconds, and may include milliseconds. See {@link #mlistDir()}
     *
     * @return The list of file information contained in the current directory
     *         in the format determined by the autodetection mechanism.
     *         <p><b>
     *         NOTE:</b> This array may contain null members if any of the
     *         individual file listings failed to parse.  The caller should
     *         check each entry for null before referencing it.
     * @throws FTPConnectionClosedException
     *                   If the FTP server prematurely closes the connection
     *                   as a result of the client being idle or some other
     *                   reason causing the server to send FTP reply code 421.
     *                   This exception may be caught either as an IOException
     *                   or independently as itself.
     * @throws IOException
     *                   If an I/O error occurs while either sending a
     *                   command to the server or receiving a reply
     *                   from the server.
     * @throws org.apache.commons.net.ftp.parser.ParserInitializationException
     *                   Thrown if the parserKey parameter cannot be
     *                   resolved by the selected parser factory.
     *                   In the DefaultFTPEntryParserFactory, this will
     *                   happen when parserKey is neither
     *                   the fully qualified class name of a class
     *                   implementing the interface
     *                   org.apache.commons.net.ftp.FTPFileEntryParser
     *                   nor a string containing one of the recognized keys
     *                   mapping to such a parser or if class loader
     *                   security issues prevent its being loaded.
     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
     * @see org.apache.commons.net.ftp.FTPFileEntryParser
     */
    public FTPFile[] listFiles()
    throws IOException
    {
        return listFiles((String) null);
    }

    /**
     * Version of {@link #listFiles(String)} which allows a filter to be provided.
     * For example: <code>listFiles("site", FTPFileFilters.DIRECTORY);</code>
     * @param pathname the initial path, may be null
     * @param filter the filter, non-null
     * @return the list of FTPFile entries.
     * @throws IOException on error
     * @since 2.2
     */
    public FTPFile[] listFiles(String pathname, FTPFileFilter filter)
    throws IOException
    {
        FTPListParseEngine engine = initiateListParsing((String) null, pathname);
        return engine.getFiles(filter);

    }

    /**
     * Using the default system autodetect mechanism, obtain a
     * list of directories contained in the current working directory.
     * <p>
     * This information is obtained through the LIST command.  The contents of
     * the returned array is determined by the<code> FTPFileEntryParser </code>
     * used.
     * <p>
     * N.B. the LIST command does not generally return very precise timestamps.
     * For recent files, the response usually contains hours and minutes (not seconds).
     * For older files, the output may only contain a date.
     * If the server supports it, the MLSD command returns timestamps with a precision
     * of seconds, and may include milliseconds. See {@link #mlistDir()}
     *
     * @return The list of directories contained in the current directory
     *         in the format determined by the autodetection mechanism.
     *
     * @throws FTPConnectionClosedException
     *                   If the FTP server prematurely closes the connection
     *                   as a result of the client being idle or some other
     *                   reason causing the server to send FTP reply code 421.
     *                   This exception may be caught either as an IOException
     *                   or independently as itself.
     * @throws IOException
     *                   If an I/O error occurs while either sending a
     *                   command to the server or receiving a reply
     *                   from the server.
     * @throws org.apache.commons.net.ftp.parser.ParserInitializationException
     *                   Thrown if the parserKey parameter cannot be
     *                   resolved by the selected parser factory.
     *                   In the DefaultFTPEntryParserFactory, this will
     *                   happen when parserKey is neither
     *                   the fully qualified class name of a class
     *                   implementing the interface
     *                   org.apache.commons.net.ftp.FTPFileEntryParser
     *                   nor a string containing one of the recognized keys
     *                   mapping to such a parser or if class loader
     *                   security issues prevent its being loaded.
     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
     * @see org.apache.commons.net.ftp.FTPFileEntryParser
     * @since 3.0
     */
    public FTPFile[] listDirectories() throws IOException {
        return listDirectories((String) null);
    }

    /**
     * Using the default system autodetect mechanism, obtain a
     * list of directories contained in the specified directory.
     * <p>
     * This information is obtained through the LIST command.  The contents of
     * the returned array is determined by the<code> FTPFileEntryParser </code>
     * used.
     * <p>
     * N.B. the LIST command does not generally return very precise timestamps.
     * For recent files, the response usually contains hours and minutes (not seconds).
     * For older files, the output may only contain a date.
     * If the server supports it, the MLSD command returns timestamps with a precision
     * of seconds, and may include milliseconds. See {@link #mlistDir()}
     * @param parent the starting directory
     *
     * @return The list of directories contained in the specified directory
     *         in the format determined by the autodetection mechanism.
     *
     * @throws FTPConnectionClosedException
     *                   If the FTP server prematurely closes the connection
     *                   as a result of the client being idle or some other
     *                   reason causing the server to send FTP reply code 421.
     *                   This exception may be caught either as an IOException
     *                   or independently as itself.
     * @throws IOException
     *                   If an I/O error occurs while either sending a
     *                   command to the server or receiving a reply
     *                   from the server.
     * @throws org.apache.commons.net.ftp.parser.ParserInitializationException
     *                   Thrown if the parserKey parameter cannot be
     *                   resolved by the selected parser factory.
     *                   In the DefaultFTPEntryParserFactory, this will
     *                   happen when parserKey is neither
     *                   the fully qualified class name of a class
     *                   implementing the interface
     *                   org.apache.commons.net.ftp.FTPFileEntryParser
     *                   nor a string containing one of the recognized keys
     *                   mapping to such a parser or if class loader
     *                   security issues prevent its being loaded.
     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
     * @see org.apache.commons.net.ftp.FTPFileEntryParser
     * @since 3.0
     */
    public FTPFile[] listDirectories(String parent) throws IOException {
        return listFiles(parent, FTPFileFilters.DIRECTORIES);
    }

    /**
     * Using the default autodetect mechanism, initialize an FTPListParseEngine
     * object containing a raw file information for the current working
     * directory on the server
     * This information is obtained through the LIST command.  This object
     * is then capable of being iterated to return a sequence of FTPFile
     * objects with information filled in by the
     * <code> FTPFileEntryParser </code> used.
     * <p>
     * This method differs from using the listFiles() methods in that
     * expensive FTPFile objects are not created until needed which may be
     * an advantage on large lists.
     *
     * @return A FTPListParseEngine object that holds the raw information and
     * is capable of providing parsed FTPFile objects, one for each file
     * containing information contained in the given path in the format
     * determined by the <code> parser </code> parameter.   Null will be
     * returned if a data connection cannot be opened.  If the current working
     * directory contains no files, an empty array will be the return.
     *
     * @throws FTPConnectionClosedException
     *                   If the FTP server prematurely closes the connection as a result
     *                   of the client being idle or some other reason causing the server
     *                   to send FTP reply code 421.  This exception may be caught either
     *                   as an IOException or independently as itself.
     * @throws IOException
     *                   If an I/O error occurs while either sending a
     *                   command to the server or receiving a reply from the server.
     * @throws org.apache.commons.net.ftp.parser.ParserInitializationException
     *                   Thrown if the autodetect mechanism cannot
     *                   resolve the type of system we are connected with.
     * @see FTPListParseEngine
     */
    public FTPListParseEngine initiateListParsing()
    throws IOException
    {
        return initiateListParsing((String) null);
    }

    /**
     * Using the default autodetect mechanism, initialize an FTPListParseEngine
     * object containing a raw file information for the supplied directory.
     * This information is obtained through the LIST command.  This object
     * is then capable of being iterated to return a sequence of FTPFile
     * objects with information filled in by the
     * <code> FTPFileEntryParser </code> used.
     * <p>
     * The server may or may not expand glob expressions.  You should avoid
     * using glob expressions because the return format for glob listings
     * differs from server to server and will likely cause this method to fail.
     * <p>
     * This method differs from using the listFiles() methods in that
     * expensive FTPFile objects are not created until needed which may be
     * an advantage on large lists.
     *
     * <pre>
     *    FTPClient f=FTPClient();
     *    f.connect(server);
     *    f.login(username, password);
     *    FTPListParseEngine engine = f.initiateListParsing(directory);
     *
     *    while (engine.hasNext()) {
     *       FTPFile[] files = engine.getNext(25);  // "page size" you want
     *       //do whatever you want with these files, display them, etc.
     *       //expensive FTPFile objects not created until needed.
     *    }
     * </pre>
     * @param pathname the starting directory
     *
     * @return A FTPListParseEngine object that holds the raw information and
     * is capable of providing parsed FTPFile objects, one for each file
     * containing information contained in the given path in the format
     * determined by the <code> parser </code> parameter.   Null will be
     * returned if a data connection cannot be opened.  If the current working
     * directory contains no files, an empty array will be the return.
     *
     * @throws FTPConnectionClosedException
     *                   If the FTP server prematurely closes the connection as a result
     *                   of the client being idle or some other reason causing the server
     *                   to send FTP reply code 421.  This exception may be caught either
     *                   as an IOException or independently as itself.
     * @throws IOException
     *                   If an I/O error occurs while either sending a
     *                   command to the server or receiving a reply from the server.
     * @throws org.apache.commons.net.ftp.parser.ParserInitializationException
     *                   Thrown if the autodetect mechanism cannot
     *                   resolve the type of system we are connected with.
     * @see FTPListParseEngine
     */
    public FTPListParseEngine initiateListParsing(String pathname)
    throws IOException
    {
        return initiateListParsing((String) null, pathname);
    }

    /**
     * Using the supplied parser key, initialize an FTPListParseEngine
     * object containing a raw file information for the supplied directory.
     * This information is obtained through the LIST command.  This object
     * is then capable of being iterated to return a sequence of FTPFile
     * objects with information filled in by the
     * <code> FTPFileEntryParser </code> used.
     * <p>
     * The server may or may not expand glob expressions.  You should avoid
     * using glob expressions because the return format for glob listings
     * differs from server to server and will likely cause this method to fail.
     * <p>
     * This method differs from using the listFiles() methods in that
     * expensive FTPFile objects are not created until needed which may be
     * an advantage on large lists.
     *
     * @param parserKey A string representing a designated code or fully-qualified
     * class name of an  <code> FTPFileEntryParser </code> that should be
     *               used to parse each server file listing.
     *               May be {@code null}, in which case the code checks first
     *               the system property {@link #FTP_SYSTEM_TYPE}, and if that is
     *               not defined the SYST command is used to provide the value.
     *               To allow for arbitrary system types, the return from the
     *               SYST command is used to look up an alias for the type in the
     *               {@link #SYSTEM_TYPE_PROPERTIES} properties file if it is available.
     * @param pathname the starting directory
     *
     * @return A FTPListParseEngine object that holds the raw information and
     * is capable of providing parsed FTPFile objects, one for each file
     * containing information contained in the given path in the format
     * determined by the <code> parser </code> parameter.   Null will be
     * returned if a data connection cannot be opened.  If the current working
     * directory contains no files, an empty array will be the return.
     *
     * @throws FTPConnectionClosedException
     *                   If the FTP server prematurely closes the connection as a result
     *                   of the client being idle or some other reason causing the server
     *                   to send FTP reply code 421.  This exception may be caught either
     *                   as an IOException or independently as itself.
     * @throws IOException
     *                   If an I/O error occurs while either sending a
     *                   command to the server or receiving a reply from the server.
     * @throws org.apache.commons.net.ftp.parser.ParserInitializationException
     *                   Thrown if the parserKey parameter cannot be
     *                   resolved by the selected parser factory.
     *                   In the DefaultFTPEntryParserFactory, this will
     *                   happen when parserKey is neither
     *                   the fully qualified class name of a class
     *                   implementing the interface
     *                   org.apache.commons.net.ftp.FTPFileEntryParser
     *                   nor a string containing one of the recognized keys
     *                   mapping to such a parser or if class loader
     *                   security issues prevent its being loaded.
     * @see FTPListParseEngine
     */
    public FTPListParseEngine initiateListParsing(
            String parserKey, String pathname)
    throws IOException
    {
        __createParser(parserKey); // create and cache parser
        return initiateListParsing(__entryParser, pathname);
    }

    // package access for test purposes
    void __createParser(String parserKey) throws IOException {
        // We cache the value to avoid creation of a new object every
        // time a file listing is generated.
        // Note: we don't check against a null parserKey (NET-544)
        if(__entryParser == null ||  (parserKey != null && ! __entryParserKey.equals(parserKey))) {
            if (null != parserKey) {
                // if a parser key was supplied in the parameters,
                // use that to create the parser
                __entryParser =
                    __parserFactory.createFileEntryParser(parserKey);
                __entryParserKey = parserKey;

            } else {
                // if no parserKey was supplied, check for a configuration
                // in the params, and if it has a non-empty system type, use that.
                if (null != __configuration && __configuration.getServerSystemKey().length() > 0) {
                    __entryParser =
                        __parserFactory.createFileEntryParser(__configuration);
                    __entryParserKey = __configuration.getServerSystemKey();
                } else {
                    // if a parserKey hasn't been supplied, and a configuration
                    // hasn't been supplied, and the override property is not set
                    // then autodetect by calling
                    // the SYST command and use that to choose the parser.
                    String systemType = System.getProperty(FTP_SYSTEM_TYPE);
                    if (systemType == null) {
                        systemType = getSystemType(); // cannot be null
                        Properties override = getOverrideProperties();
                        if (override != null) {
                            String newType = override.getProperty(systemType);
                            if (newType != null) {
                                systemType = newType;
                            }
                        }
                    }
                    if (null != __configuration) { // system type must have been empty above
                        __entryParser = __parserFactory.createFileEntryParser(new FTPClientConfig(systemType, __configuration));
                    } else {
                        __entryParser = __parserFactory.createFileEntryParser(systemType);
                    }
                    __entryParserKey = systemType;
                }
            }
        }


    }

    /**
     * private method through which all listFiles() and
     * initiateListParsing methods pass once a parser is determined.
     *
     * @throws FTPConnectionClosedException
     *                   If the FTP server prematurely closes the connection as a result
     *                   of the client being idle or some other reason causing the server
     *                   to send FTP reply code 421.  This exception may be caught either
     *                   as an IOException or independently as itself.
     * @throws IOException
     *                   If an I/O error occurs while either sending a
     *                   command to the server or receiving a reply from the server.
     * @see FTPListParseEngine
     */
    private FTPListParseEngine initiateListParsing(
            FTPFileEntryParser parser, String pathname)
    throws IOException
    {
        Socket socket = _openDataConnection_(FTPCmd.LIST, getListArguments(pathname));

        FTPListParseEngine engine = new FTPListParseEngine(parser, __configuration);
        if (socket == null)
        {
            return engine;
        }

        try {
            engine.readServerList(socket.getInputStream(), getControlEncoding());
        }
        finally {
            Util.closeQuietly(socket);
        }

        completePendingCommand();
        return engine;
    }

    /**
     * Initiate list parsing for MLSD listings.
     *
     * @param pathname
     * @return the engine
     * @throws IOException
     */
    private FTPListParseEngine initiateMListParsing(String pathname) throws IOException
    {
        Socket socket = _openDataConnection_(FTPCmd.MLSD, pathname);
        FTPListParseEngine engine = new FTPListParseEngine(MLSxEntryParser.getInstance(), __configuration);
        if (socket == null)
        {
            return engine;
        }

        try {
            engine.readServerList(socket.getInputStream(), getControlEncoding());
        }
        finally {
            Util.closeQuietly(socket);
            completePendingCommand();
        }
        return engine;
    }

    /**
     * @param pathname the initial pathname
     * @return the adjusted string with "-a" added if necessary
     * @since 2.0
     */
    protected String getListArguments(String pathname) {
        if (getListHiddenFiles())
        {
            if (pathname != null)
            {
                StringBuilder sb = new StringBuilder(pathname.length() + 3);
                sb.append("-a ");
                sb.append(pathname);
                return sb.toString();
            }
            else
            {
                return "-a";
            }
        }

        return pathname;
    }


    /**
     * Issue the FTP STAT command to the server.
     *
     * @return The status information returned by the server.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public String getStatus() throws IOException
    {
        if (FTPReply.isPositiveCompletion(stat())) {
            return getReplyString();
        }
        return null;
    }


    /**
     * Issue the FTP STAT command to the server for a given pathname.  This
     * should produce a listing of the file or directory.
     * @param pathname the filename
     *
     * @return The status information returned by the server.
     * @throws FTPConnectionClosedException
     *      If the FTP server prematurely closes the connection as a result
     *      of the client being idle or some other reason causing the server
     *      to send FTP reply code 421.  This exception may be caught either
     *      as an IOException or independently as itself.
     * @throws IOException  If an I/O error occurs while either sending a
     *      command to the server or receiving a reply from the server.
     */
    public String getStatus(String pathname) throws IOException
    {
        if (FTPReply.isPositiveCompletion(stat(pathname))) {
            return getReplyString();
        }
        return null;
    }


    /**
     * Issue the FTP MDTM command (not supported by all servers) to retrieve the last
     * modification time of a file. The modification string should be in the
     * ISO 3077 form "YYYYMMDDhhmmss(.xxx)?". The timestamp represented should also be in
     * GMT, but not all FTP servers honour this.
     *
     * @param pathname The file path to query.
     * @return A string representing the last file modification time in <code>YYYYMMDDhhmmss</code> format.
     * @throws IOException if an I/O error occurs.
     * @since 2.0
     */
    public String getModificationTime(String pathname) throws IOException {
        if (FTPReply.isPositiveCompletion(mdtm(pathname))) {
            return getReplyStrings()[0].substring(4); // skip the return code (e.g. 213) and the space
        }
        return null;
    }


    /**
     * Issue the FTP MDTM command (not supported by all servers) to retrieve the last
     * modification time of a file. The modification string should be in the
     * ISO 3077 form "YYYYMMDDhhmmss(.xxx)?". The timestamp represented should also be in
     * GMT, but not all FTP servers honour this.
     *
     * @param pathname The file path to query.
     * @return A FTPFile representing the last file modification time, may be {@code null}.
     * The FTPFile timestamp will be null if a parse error occurs.
     * @throws IOException if an I/O error occurs.
     * @since 3.4
     */
    public FTPFile mdtmFile(String pathname) throws IOException {
        if (FTPReply.isPositiveCompletion(mdtm(pathname))) {
            String reply = getReplyStrings()[0].substring(4); // skip the return code (e.g. 213) and the space
            FTPFile file = new FTPFile();
            file.setName(pathname);
            file.setRawListing(reply);
            file.setTimestamp(MLSxEntryParser.parseGMTdateTime(reply));
            return file;
        }
        return null;
    }


    /**
     * Issue the FTP MFMT command (not supported by all servers) which sets the last
     * modified time of a file.
     *
     * The timestamp should be in the form <code>YYYYMMDDhhmmss</code>. It should also
     * be in GMT, but not all servers honour this.
     *
     * An FTP server would indicate its support of this feature by including "MFMT"
     * in its response to the FEAT command, which may be retrieved by FTPClient.features()
     *
     * @param pathname The file path for which last modified time is to be changed.
     * @param timeval The timestamp to set to, in <code>YYYYMMDDhhmmss</code> format.
     * @return true if successfully set, false if not
     * @throws IOException if an I/O error occurs.
     * @since 2.2
     * @see <a href="http://tools.ietf.org/html/draft-somers-ftp-mfxx-04">http://tools.ietf.org/html/draft-somers-ftp-mfxx-04</a>
     */
    public boolean setModificationTime(String pathname, String timeval) throws IOException {
        return (FTPReply.isPositiveCompletion(mfmt(pathname, timeval)));
    }


    /**
     * Set the internal buffer size for buffered data streams.
     *
     * @param bufSize The size of the buffer. Use a non-positive value to use the default.
     */
    public void setBufferSize(int bufSize) {
        __bufferSize = bufSize;
    }

    /**
     * Retrieve the current internal buffer size for buffered data streams.
     * @return The current buffer size.
     */
    public int getBufferSize() {
        return __bufferSize;
    }

    /**
     * Sets the value to be used for the data socket SO_SNDBUF option.
     * If the value is positive, the option will be set when the data socket has been created.
     *
     * @param bufSize The size of the buffer, zero or negative means the value is ignored.
      * @since 3.3
    */
    public void setSendDataSocketBufferSize(int bufSize) {
        __sendDataSocketBufferSize = bufSize;
    }

    /**
     * Retrieve the value to be used for the data socket SO_SNDBUF option.
     * @return The current buffer size.
     * @since 3.3
     */
    public int getSendDataSocketBufferSize() {
        return __sendDataSocketBufferSize;
    }

    /**
     * Sets the value to be used for the data socket SO_RCVBUF option.
     * If the value is positive, the option will be set when the data socket has been created.
     *
     * @param bufSize The size of the buffer, zero or negative means the value is ignored.
     * @since 3.3
     */
    public void setReceieveDataSocketBufferSize(int bufSize) {
        __receiveDataSocketBufferSize = bufSize;
    }

    /**
     * Retrieve the value to be used for the data socket SO_RCVBUF option.
     * @return The current buffer size.
     * @since 3.3
     */
    public int getReceiveDataSocketBufferSize() {
        return __receiveDataSocketBufferSize;
    }

    /**
     * Implementation of the {@link Configurable Configurable} interface.
     * In the case of this class, configuring merely makes the config object available for the
     * factory methods that construct parsers.
     * @param config {@link FTPClientConfig FTPClientConfig} object used to
     * provide non-standard configurations to the parser.
     * @since 1.4
     */
    @Override
    public void configure(FTPClientConfig config) {
        this.__configuration = config;
    }

    /**
     * You can set this to true if you would like to get hidden files when {@link #listFiles} too.
     * A <code>LIST -a</code> will be issued to the ftp server.
     * It depends on your ftp server if you need to call this method, also dont expect to get rid
     * of hidden files if you call this method with "false".
     *
     * @param listHiddenFiles true if hidden files should be listed
     * @since 2.0
     */
    public void setListHiddenFiles(boolean listHiddenFiles) {
        this.__listHiddenFiles = listHiddenFiles;
    }

    /**
     * @see #setListHiddenFiles(boolean)
     * @return the current state
     * @since 2.0
     */
    public boolean getListHiddenFiles() {
        return this.__listHiddenFiles;
    }

    /**
     * Whether should attempt to use EPSV with IPv4.
     * Default (if not set) is <code>false</code>
     * @return true if should attempt EPSV
     * @since 2.2
     */
    public boolean isUseEPSVwithIPv4() {
        return __useEPSVwithIPv4;
    }


    /**
     * Set whether to use EPSV with IPv4.
     * Might be worth enabling in some circumstances.
     *
     * For example, when using IPv4 with NAT it
     * may work with some rare configurations.
     * E.g. if FTP server has a static PASV address (external network)
     * and the client is coming from another internal network.
     * In that case the data connection after PASV command would fail,
     * while EPSV would make the client succeed by taking just the port.
     *
     * @param selected value to set.
     * @since 2.2
     */
    public void setUseEPSVwithIPv4(boolean selected) {
        this.__useEPSVwithIPv4 = selected;
    }

    /**
     * Set the listener to be used when performing store/retrieve operations.
     * The default value (if not set) is {@code null}.
     *
     * @param listener to be used, may be {@code null} to disable
     * @since 3.0
     */
    public void setCopyStreamListener(CopyStreamListener listener){
        __copyStreamListener = listener;
    }

    /**
     * Obtain the currently active listener.
     *
     * @return the listener, may be {@code null}
     * @since 3.0
     */
    public CopyStreamListener getCopyStreamListener(){
        return __copyStreamListener;
    }

    /**
     * Set the time to wait between sending control connection keepalive messages
     * when processing file upload or download.
     * <p>
     * See the class Javadoc section "Control channel keep-alive feature:"
     *
     * @param controlIdle the wait (in secs) between keepalive messages. Zero (or less) disables.
     * @since 3.0
     * @see #setControlKeepAliveReplyTimeout(int)
     */
    public void setControlKeepAliveTimeout(long controlIdle){
        __controlKeepAliveTimeout = controlIdle * 1000;
    }

    /**
     * Get the time to wait between sending control connection keepalive messages
     * when processing file upload or download.
     * <p>
     * See the class Javadoc section "Control channel keep-alive feature:"
     *
     * @return the number of seconds between keepalive messages.
     * @since 3.0
     */
    public long getControlKeepAliveTimeout() {
        return __controlKeepAliveTimeout / 1000;
    }

    /**
     * Get the CSL debug array.
     * <p>
     * <b>For debug use only</b>
     * <p>
     * Currently contains:
     * <ul>
     * <li>successfully acked NOOPs at end of transfer</li>
     * <li>unanswered NOOPs at end of transfer</li>
     * <li>unanswered NOOPs after fetching additional replies</li>
     * <li>Number of IOErrors ignored</li>
     * </ul>
     * @return the debug array
     * @deprecated 3.7 For testing only; may be dropped or changed at any time
     */
    @Deprecated // only for use in testing
    public int[] getCslDebug() {
        return __cslDebug;
    }
    /**
     * Set how long to wait for control keep-alive message replies.
     *
     * @param timeout number of milliseconds to wait (defaults to 1000)
     * @since 3.0
     * @see #setControlKeepAliveTimeout(long)
     */
    public void setControlKeepAliveReplyTimeout(int timeout) {
        __controlKeepAliveReplyTimeout = timeout;
    }

    /**
     * Get how long to wait for control keep-alive message replies.
     * @return wait time in msec
     * @since 3.0
     */
    public int getControlKeepAliveReplyTimeout() {
        return __controlKeepAliveReplyTimeout;
    }

    /**
     * Enable or disable passive mode NAT workaround.
     * If enabled, a site-local PASV mode reply address will be replaced with the
     * remote host address to which the PASV mode request was sent
     * (unless that is also a site local address).
     * This gets around the problem that some NAT boxes may change the
     * reply.
     *
     * The default is true, i.e. site-local replies are replaced.
     * @param enabled true to enable replacing internal IP's in passive
     * mode.
     * @deprecated (3.6) use {@link #setPassiveNatWorkaroundStrategy(HostnameResolver)} instead
     */
    @Deprecated
    public void setPassiveNatWorkaround(boolean enabled) {
        if (enabled) {
            this.__passiveNatWorkaroundStrategy = new NatServerResolverImpl(this);
        } else {
            this.__passiveNatWorkaroundStrategy = null;
        }
    }

    /**
     * Set the workaround strategy to replace the PASV mode reply addresses.
     * This gets around the problem that some NAT boxes may change the reply.
     *
     * The default implementation is {@code NatServerResolverImpl}, i.e. site-local
     * replies are replaced.
     * @param resolver strategy to replace internal IP's in passive mode
     * or null to disable the workaround (i.e. use PASV mode reply address.)
     * @since 3.6
     */
    public void setPassiveNatWorkaroundStrategy(HostnameResolver resolver) {
        this.__passiveNatWorkaroundStrategy = resolver;
    }

    /**
     * Strategy interface for updating host names received from FTP server
     * for passive NAT workaround.
     *
     * @since 3.6
     */
    public static interface HostnameResolver {
        String resolve(String hostname) throws UnknownHostException;
    }

    /**
     * Default strategy for passive NAT workaround (site-local
     * replies are replaced.)
     * @since 3.6
     */
    public static class NatServerResolverImpl implements HostnameResolver {
        private FTPClient client;

        public NatServerResolverImpl(FTPClient client) {
            this.client = client;
        }

        @Override
        public String resolve(String hostname) throws UnknownHostException {
            String newHostname = hostname;
            InetAddress host = InetAddress.getByName(newHostname);
            // reply is a local address, but target is not - assume NAT box changed the PASV reply
            if (host.isSiteLocalAddress()) {
                InetAddress remote = this.client.getRemoteAddress();
                if (!remote.isSiteLocalAddress()){
                    newHostname = remote.getHostAddress();
                }
            }
            return newHostname;
        }
    }

    private OutputStream getBufferedOutputStream(OutputStream outputStream) {
        if (__bufferSize > 0) {
            return new BufferedOutputStream(outputStream, __bufferSize);
        }
        return new BufferedOutputStream(outputStream);
    }

    private InputStream getBufferedInputStream(InputStream inputStream) {
        if (__bufferSize > 0) {
            return new BufferedInputStream(inputStream, __bufferSize);
        }
        return new BufferedInputStream(inputStream);
    }

    // @since 3.0
    private static class CSL implements CopyStreamListener {

        private final FTPClient parent;
        private final long idle;
        private final int currentSoTimeout;

        private long time = System.currentTimeMillis();
        private int notAcked;
        private int acksAcked;
        private int ioErrors;

        CSL(FTPClient parent, long idleTime, int maxWait) throws SocketException {
            this.idle = idleTime;
            this.parent = parent;
            this.currentSoTimeout = parent.getSoTimeout();
            parent.setSoTimeout(maxWait);
        }

        @Override
        public void bytesTransferred(CopyStreamEvent event) {
            bytesTransferred(event.getTotalBytesTransferred(), event.getBytesTransferred(), event.getStreamSize());
        }

        @Override
        public void bytesTransferred(long totalBytesTransferred,
                int bytesTransferred, long streamSize) {
            long now = System.currentTimeMillis();
            if (now - time > idle) {
                try {
                    parent.__noop();
                    acksAcked++;
                } catch (SocketTimeoutException e) {
                    notAcked++;
                } catch (IOException e) {
                    ioErrors++;
                    // Ignored
                }
                time = now;
            }
        }

        int[] cleanUp() throws IOException {
            int remain = notAcked;
            try {
                while(notAcked > 0) {
                    parent.getReply(); // we do want to see these
                    notAcked--; // only decrement if actually received
                }
            } catch (SocketTimeoutException e) { // NET-584
                // ignored
            } finally {
                parent.setSoTimeout(currentSoTimeout);
            }
            return new int [] {acksAcked, remain, notAcked, ioErrors}; // debug counts
        }

    }

    /**
     * Merge two copystream listeners, either or both of which may be null.
     *
     * @param local the listener used by this class, may be null
     * @return a merged listener or a single listener or null
     * @since 3.0
     */
    private CopyStreamListener __mergeListeners(CopyStreamListener local) {
        if (local == null) {
            return __copyStreamListener;
        }
        if (__copyStreamListener == null) {
            return local;
        }
        // Both are non-null
        CopyStreamAdapter merged = new CopyStreamAdapter();
        merged.addCopyStreamListener(local);
        merged.addCopyStreamListener(__copyStreamListener);
        return merged;
    }

    /**
     * Enables or disables automatic server encoding detection (only UTF-8 supported).
     * <p>
     * Does not affect existing connections; must be invoked before a connection is established.
     *
     * @param autodetect If true, automatic server encoding detection will be enabled.
     */
    public void setAutodetectUTF8(boolean autodetect)
    {
        __autodetectEncoding = autodetect;
    }

    /**
     * Tells if automatic server encoding detection is enabled or disabled.
     * @return true, if automatic server encoding detection is enabled.
     */
    public boolean getAutodetectUTF8()
    {
        return __autodetectEncoding;
    }

    // Method for use by unit test code only
    FTPFileEntryParser getEntryParser() {
        return __entryParser;
    }

    // DEPRECATED METHODS - for API compatibility only - DO NOT USE

    /**
     * @return the name
     * @throws IOException on error
     * @deprecated use {@link #getSystemType()} instead
     */
    @Deprecated
    public String getSystemName() throws IOException
    {
        if (__systemName == null && FTPReply.isPositiveCompletion(syst())) {
            __systemName = _replyLines.get(_replyLines.size() - 1).substring(4);
        }
        return __systemName;
    }
}

/* Emacs configuration
 * Local variables:        **
 * mode:             java  **
 * c-basic-offset:   4     **
 * indent-tabs-mode: nil   **
 * End:                    **
 */
/* kate: indent-width 4; replace-tabs on; */
