@Override
    public void connect() throws NotConnectedException, IOException,
            AuthenticationNotSupportedException, FtpIOException,
            FtpWorkflowException {
        
        setConnectionStatusLock(FTPConnection.CSL_INDIRECT_CALL);
        
        socketProvider = new SocketProvider();
        // Only for logging
        String hostAndPort = getAddress().getHostName() + ":"
                + getAddress().getPort();
        try {
            socketProvider.socket().setSoTimeout(getTimeout());
            socketProvider.connect(getAddress(), getProxy(),
                    getDownloadBandwidth(), getUploadBandwidth());
            log.debug("connected to:" + hostAndPort);     
            socketProvider.socket().setKeepAlive(true);
        } catch (IOException ioe) {
            String error = "Error connection to:" + hostAndPort;
            log.error(error, ioe);
            throw new NotConnectedException(error);
        }
        
        Reply connectReply = ReplyWorker.readReply(this.socketProvider);
        if (connectReply != null)
            this.fireReplyMessageArrived(new FTPEvent(this, this.getConnectionStatus(), connectReply));        
        connectReply.dumpReply();
        
        Reply reply = sendCommand(new Command(Command.USER, getUser()));
        reply.dumpReply();
        reply.validate();
        if (getPassword() != null && getPassword().length() > 0) {
            reply = sendCommand(new Command(Command.PASS, getPassword()));
            reply.dumpReply();
            reply.validate();
        }
        if (getAccount() != null && getAccount().length() > 0) {
            reply = sendCommand(new Command(Command.ACCT, getAccount()));
            reply.dumpReply();
            reply.validate();
        }
        checkFeatures();
        this.setConnectionStatus(FTPConnection.CONNECTED);
        this.setConnectionStatus(FTPConnection.IDLE);
 
        checkSystem();
        
        setConnectionStatusLock(FTPConnection.CSL_DIRECT_CALL);
    }