public Result execute(Result previousResult, int nr) {
    Result result = previousResult;
    result.setResult(false);

    try {

      // Get real variable value
      String realServerName = environmentSubstitute(serverName);
      int realServerPort = Const.toInt(environmentSubstitute(serverPort), 22);
      String realUserName = environmentSubstitute(userName);
      String realServerPassword =
          Encr.decryptPasswordOptionallyEncrypted(environmentSubstitute(password));
      // Proxy Host
      String realProxyHost = environmentSubstitute(httpproxyhost);
      int realProxyPort = Const.toInt(environmentSubstitute(httpproxyport), 22);
      String realproxyUserName = environmentSubstitute(httpproxyusername);
      String realProxyPassword =
          Encr.decryptPasswordOptionallyEncrypted(environmentSubstitute(httpProxyPassword));
      // Key file
      String realKeyFilename = environmentSubstitute(keyFilename);
      String relKeyFilepass = environmentSubstitute(keyFilePass);
      // Source files
      String realLocalDirectory = environmentSubstitute(localDirectory);
      String realwildcard = environmentSubstitute(wildcard);
      // Remote destination
      String realftpDirectory = environmentSubstitute(ftpDirectory);
      // Destination folder (Move to)
      String realDestinationFolder = environmentSubstitute(destinationfolder);

      try {
        // Remote source
        realftpDirectory = FTPUtils.normalizePath(realftpDirectory);
        // Destination folder (Move to)
        realDestinationFolder = FTPUtils.normalizePath(realDestinationFolder);
      } catch (Exception e) {
        logError(BaseMessages.getString(PKG, "JobSSH2PUT.Log.CanNotNormalizePath", e.getMessage()));
        result.setNrErrors(1);
        return result;
      }

      // Check for mandatory fields
      boolean mandatoryok = true;
      if (Const.isEmpty(realServerName)) {
        mandatoryok = false;
        logError(BaseMessages.getString(PKG, "JobSSH2PUT.Log.ServernameMissing"));
      }
      if (usehttpproxy) {
        if (Const.isEmpty(realProxyHost)) {
          mandatoryok = false;
          logError(BaseMessages.getString(PKG, "JobSSH2PUT.Log.HttpProxyhostMissing"));
        }
      }
      if (publicpublickey) {
        if (Const.isEmpty(realKeyFilename)) {
          mandatoryok = false;
          logError(BaseMessages.getString(PKG, "JobSSH2PUT.Log.KeyFileMissing"));
        } else {
          // Let's check if folder exists...
          if (!KettleVFS.fileExists(realKeyFilename, this)) {
            mandatoryok = false;
            logError(BaseMessages.getString(PKG, "JobSSH2PUT.Log.KeyFileNotExist"));
          }
        }
      }

      if (Const.isEmpty(realLocalDirectory)) {
        mandatoryok = false;
        logError(BaseMessages.getString(PKG, "JobSSH2PUT.Log.LocalFolderMissing"));
      }
      if (afterFtpPut.equals("move_file")) {
        if (Const.isEmpty(realDestinationFolder)) {
          mandatoryok = false;
          logError(BaseMessages.getString(PKG, "JobSSH2PUT.Log.DestinatFolderMissing"));
        } else {
          FileObject folder = null;
          try {
            folder = KettleVFS.getFileObject(realDestinationFolder, this);
            // Let's check if folder exists...
            if (!folder.exists()) {
              // Do we need to create it?
              if (createDestinationFolder) {
                folder.createFolder();
              } else {
                logError(
                    BaseMessages.getString(
                        PKG, "JobSSH2PUT.Log.DestinatFolderNotExist", realDestinationFolder));
              }
            }
          } catch (Exception e) {
            throw new KettleException(e);
          } finally {
            if (folder != null) {
              try {
                folder.close();
                folder = null;
              } catch (Exception e) {
                /* Ignore */
              }
            }
          }
        }
      }

      if (mandatoryok) {
        Connection conn = null;
        SFTPv3Client client = null;
        boolean good = true;

        int nbfilestoput = 0;
        int nbput = 0;
        int nbrerror = 0;

        try {
          // Create a connection instance
          conn =
              getConnection(
                  realServerName,
                  realServerPort,
                  realProxyHost,
                  realProxyPort,
                  realproxyUserName,
                  realProxyPassword);

          if (timeout > 0) {
            // Use timeout
            // Cache Host Key
            if (cachehostkey) {
              conn.connect(new SimpleVerifier(database), 0, timeout * 1000);
            } else {
              conn.connect(null, 0, timeout * 1000);
            }

          } else {
            // Cache Host Key
            if (cachehostkey) {
              conn.connect(new SimpleVerifier(database));
            } else {
              conn.connect();
            }
          }

          // Authenticate

          boolean isAuthenticated = false;
          if (publicpublickey) {
            String keyContent =
                KettleVFS.getTextFileContent(realKeyFilename, this, Const.XML_ENCODING);
            isAuthenticated =
                conn.authenticateWithPublicKey(
                    realUserName, keyContent.toCharArray(), relKeyFilepass);
          } else {
            isAuthenticated = conn.authenticateWithPassword(realUserName, realServerPassword);
          }

          // LET'S CHECK AUTHENTICATION ...
          if (isAuthenticated == false) {
            logError(BaseMessages.getString(PKG, "JobSSH2PUT.Log.AuthenticationFailed"));
          } else {
            if (log.isBasic()) {
              logBasic(
                  BaseMessages.getString(PKG, "JobSSH2PUT.Log.Connected", serverName, userName));
            }

            client = new SFTPv3Client(conn);

            if (log.isDetailed()) {
              logDetailed(
                  BaseMessages.getString(
                      PKG, "JobSSH2PUT.Log.ProtocolVersion", "" + client.getProtocolVersion()));
            }

            // Check if remote directory exists
            if (!Const.isEmpty(realftpDirectory)) {
              if (!sshDirectoryExists(client, realftpDirectory)) {
                good = false;
                if (createRemoteFolder) {
                  good = CreateRemoteFolder(client, realftpDirectory);
                  if (good) {
                    logBasic(BaseMessages.getString(PKG, "JobSSH2PUT.Log.RemoteDirectoryCreated"));
                  }

                } else {
                  logError(
                      BaseMessages.getString(
                          PKG, "JobSSH2PUT.Log.RemoteDirectoryNotExist", realftpDirectory));
                }
              } else if (log.isDetailed()) {
                logDetailed(
                    BaseMessages.getString(
                        PKG, "JobSSH2PUT.Log.RemoteDirectoryExist", realftpDirectory));
              }
            }

            if (good) {
              // Get files list from local folder (source)
              List<FileObject> myFileList = getFiles(realLocalDirectory);

              // Prepare Pattern for wildcard
              Pattern pattern = null;
              if (!Const.isEmpty(realwildcard)) {
                pattern = Pattern.compile(realwildcard);
              }

              // Let's put files now ...
              // Get the files in the list
              for (int i = 0; i < myFileList.size() && !parentJob.isStopped(); i++) {
                FileObject myFile = myFileList.get(i);
                String localFilename = myFile.toString();
                String remoteFilename = myFile.getName().getBaseName();

                boolean getIt = true;

                // First see if the file matches the regular expression!
                if (pattern != null) {
                  Matcher matcher = pattern.matcher(remoteFilename);
                  getIt = matcher.matches();
                }

                // do we have a target directory?
                if (!Const.isEmpty(realftpDirectory)) {
                  remoteFilename = realftpDirectory + FTPUtils.FILE_SEPARATOR + remoteFilename;
                }

                if (onlyGettingNewFiles) {
                  // We get only new files
                  // ie not exist on the remote server
                  getIt = !sshFileExists(client, remoteFilename);
                }

                if (getIt) {
                  nbfilestoput++;

                  boolean putok = putFile(myFile, remoteFilename, client);
                  if (!putok) {
                    nbrerror++;
                    logError(
                        BaseMessages.getString(
                            PKG, "JobSSH2PUT.Log.Error.CanNotPutFile", localFilename));
                  } else {
                    nbput++;
                  }

                  if (putok && !afterFtpPut.equals("do_nothing")) {
                    deleteOrMoveFiles(myFile, realDestinationFolder);
                  }
                }
              }
              /** ****************************** RESULT ******************* */
              if (log.isDetailed()) {
                logDetailed(BaseMessages.getString(PKG, "JobSSH2PUT.Log.Result.JobEntryEnd1"));
                logDetailed(
                    BaseMessages.getString(
                        PKG, "JobSSH2PUT.Log.Result.TotalFiles", "" + nbfilestoput));
                logDetailed(
                    BaseMessages.getString(PKG, "JobSSH2PUT.Log.Result.TotalFilesPut", "" + nbput));
                logDetailed(
                    BaseMessages.getString(
                        PKG, "JobSSH2PUT.Log.Result.TotalFilesError", "" + nbrerror));
                logDetailed(BaseMessages.getString(PKG, "JobSSH2PUT.Log.Result.JobEntryEnd2"));
              }
              if (nbrerror == 0) {
                result.setResult(true);
                /** ****************************** RESULT ******************* */
              }
            }
          }

        } catch (Exception e) {
          result.setNrErrors(nbrerror);
          logError(BaseMessages.getString(PKG, "JobSSH2PUT.Log.Error.ErrorFTP", e.getMessage()));
        } finally {
          if (conn != null) {
            conn.close();
          }
          if (client != null) {
            client.close();
          }
        }
      }
    } catch (Exception e) {
      result.setResult(false);
      result.setNrErrors(1L);
      logError(BaseMessages.getString(PKG, "JobSSH2PUT.Log.Error.UnexpectedError"), e);
    }

    return result;
  }