// Path: deploy-runner-agent/src/main/java/jetbrains/buildServer/deployer/agent/DeployerAgentUtils.java
// public class DeployerAgentUtils {
//   public static void logBuildProblem(BuildProgressLogger logger, String message) {
//     logger.logBuildProblem(BuildProblemData
//             .createBuildProblem(String.valueOf(message.hashCode()),
//                     DeployerRunnerConstants.BUILD_PROBLEM_TYPE,
//                     "Deployment problem: " + message));
//   }
// }
// 
// Path: deploy-runner-agent/src/main/java/jetbrains/buildServer/deployer/agent/SyncBuildProcessAdapter.java
// public abstract class SyncBuildProcessAdapter extends BuildProcessAdapter {
//   protected final BuildProgressLogger myLogger;
//   private volatile boolean hasFinished;
//   private volatile BuildFinishedStatus statusCode;
//   private volatile boolean isInterrupted;
// 
// 
//   public SyncBuildProcessAdapter(@NotNull final BuildProgressLogger logger) {
//     myLogger = logger;
//     hasFinished = false;
//     statusCode = null;
//   }
// 
// 
//   @Override
//   public void interrupt() {
//     isInterrupted = true;
//   }
// 
//   @Override
//   public boolean isInterrupted() {
//     return isInterrupted;
//   }
// 
//   @Override
//   public boolean isFinished() {
//     return hasFinished;
//   }
// 
//   @NotNull
//   @Override
//   public BuildFinishedStatus waitFor() throws RunBuildException {
//     while (!isInterrupted() && !hasFinished) {
//       try {
//         Thread.sleep(1000);
//       } catch (InterruptedException e) {
//         throw new RunBuildException(e);
//       }
//     }
//     return hasFinished ? statusCode : BuildFinishedStatus.INTERRUPTED;
//   }
// 
//   @Override
//   public void start() throws RunBuildException {
//     try {
//       statusCode = runProcess();
//       hasFinished = true;
//     } catch (UploadInterruptedException e) {
//       hasFinished = false;
//     }
//   }
// 
//   /**
//    * @return true is process finished successfully
//    */
//   protected abstract BuildFinishedStatus runProcess();
// 
//   protected void checkIsInterrupted() throws UploadInterruptedException {
//     if (isInterrupted()) throw new UploadInterruptedException();
//   }
// 
// }
// 
// Path: deploy-runner-agent/src/main/java/jetbrains/buildServer/deployer/agent/UploadInterruptedException.java
// public class UploadInterruptedException extends RuntimeException {
// 
// }


import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jetbrains.buildServer.agent.BuildFinishedStatus;
import jetbrains.buildServer.agent.BuildRunnerContext;
import jetbrains.buildServer.agent.impl.artifacts.ArtifactsCollection;
import jetbrains.buildServer.deployer.agent.DeployerAgentUtils;
import jetbrains.buildServer.deployer.agent.SyncBuildProcessAdapter;
import jetbrains.buildServer.deployer.agent.UploadInterruptedException;
import jetbrains.buildServer.log.Loggers;
import jetbrains.buildServer.util.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
    } else if (!myTarget.startsWith(SMB)) {
      targetWithProtocol = SMB + myTarget;
    } else {
      targetWithProtocol = myTarget;
    }

    // Share and directories names require trailing /
    if (!targetWithProtocol.endsWith("/")) {
      targetWithProtocol = targetWithProtocol + "/";
    }

    targetWithProtocol = targetWithProtocol.replaceAll("\\\\", "/");

    NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(myDomain == null ? "" : myDomain,
        myUsername, myPassword);

    final String settingsString = "Trying to connect with following parameters:\n" +
        "username=[" + myUsername + "]\n" +
        "domain=[" + (myDomain == null ? "" : myDomain) + "]\n" +
        "target=[" + targetWithProtocol + "]";
    try {
      Loggers.AGENT.debug(settingsString);
      myLogger.message("Starting upload via SMB to " + myTarget);
      SmbFile destinationDir = new SmbFile(targetWithProtocol, auth);

      for (ArtifactsCollection artifactsCollection : myArtifactsCollections) {
        final int numOfUploadedFiles = upload(artifactsCollection.getFilePathMap(), destinationDir);
        myLogger.message("Uploaded [" + numOfUploadedFiles + "] files for [" + artifactsCollection.getSourcePath() + "] pattern");
      }
      return BuildFinishedStatus.FINISHED_SUCCESS;
// Path: deploy-runner-agent/src/main/java/jetbrains/buildServer/deployer/agent/DeployerAgentUtils.java
// public class DeployerAgentUtils {
//   public static void logBuildProblem(BuildProgressLogger logger, String message) {
//     logger.logBuildProblem(BuildProblemData
//             .createBuildProblem(String.valueOf(message.hashCode()),
//                     DeployerRunnerConstants.BUILD_PROBLEM_TYPE,
//                     "Deployment problem: " + message));
//   }
// }
// 
// Path: deploy-runner-agent/src/main/java/jetbrains/buildServer/deployer/agent/SyncBuildProcessAdapter.java
// public abstract class SyncBuildProcessAdapter extends BuildProcessAdapter {
//   protected final BuildProgressLogger myLogger;
//   private volatile boolean hasFinished;
//   private volatile BuildFinishedStatus statusCode;
//   private volatile boolean isInterrupted;
// 
// 
//   public SyncBuildProcessAdapter(@NotNull final BuildProgressLogger logger) {
//     myLogger = logger;
//     hasFinished = false;
//     statusCode = null;
//   }
// 
// 
//   @Override
//   public void interrupt() {
//     isInterrupted = true;
//   }
// 
//   @Override
//   public boolean isInterrupted() {
//     return isInterrupted;
//   }
// 
//   @Override
//   public boolean isFinished() {
//     return hasFinished;
//   }
// 
//   @NotNull
//   @Override
//   public BuildFinishedStatus waitFor() throws RunBuildException {
//     while (!isInterrupted() && !hasFinished) {
//       try {
//         Thread.sleep(1000);
//       } catch (InterruptedException e) {
//         throw new RunBuildException(e);
//       }
//     }
//     return hasFinished ? statusCode : BuildFinishedStatus.INTERRUPTED;
//   }
// 
//   @Override
//   public void start() throws RunBuildException {
//     try {
//       statusCode = runProcess();
//       hasFinished = true;
//     } catch (UploadInterruptedException e) {
//       hasFinished = false;
//     }
//   }
// 
//   /**
//    * @return true is process finished successfully
//    */
//   protected abstract BuildFinishedStatus runProcess();
// 
//   protected void checkIsInterrupted() throws UploadInterruptedException {
//     if (isInterrupted()) throw new UploadInterruptedException();
//   }
// 
// }
// 
// Path: deploy-runner-agent/src/main/java/jetbrains/buildServer/deployer/agent/UploadInterruptedException.java
// public class UploadInterruptedException extends RuntimeException {
// 
// }


// Path: deploy-runner-agent-smb/src/main/java/jetbrains/buildServer/deployer/agent/smb/SMBBuildProcessAdapter.java
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jetbrains.buildServer.agent.BuildFinishedStatus;
import jetbrains.buildServer.agent.BuildRunnerContext;
import jetbrains.buildServer.agent.impl.artifacts.ArtifactsCollection;
import jetbrains.buildServer.deployer.agent.DeployerAgentUtils;
import jetbrains.buildServer.deployer.agent.SyncBuildProcessAdapter;
import jetbrains.buildServer.deployer.agent.UploadInterruptedException;
import jetbrains.buildServer.log.Loggers;
import jetbrains.buildServer.util.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

    } else if (!myTarget.startsWith(SMB)) {
      targetWithProtocol = SMB + myTarget;
    } else {
      targetWithProtocol = myTarget;
    }

    // Share and directories names require trailing /
    if (!targetWithProtocol.endsWith("/")) {
      targetWithProtocol = targetWithProtocol + "/";
    }

    targetWithProtocol = targetWithProtocol.replaceAll("\\\\", "/");

    NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(myDomain == null ? "" : myDomain,
        myUsername, myPassword);

    final String settingsString = "Trying to connect with following parameters:\n" +
        "username=[" + myUsername + "]\n" +
        "domain=[" + (myDomain == null ? "" : myDomain) + "]\n" +
        "target=[" + targetWithProtocol + "]";
    try {
      Loggers.AGENT.debug(settingsString);
      myLogger.message("Starting upload via SMB to " + myTarget);
      SmbFile destinationDir = new SmbFile(targetWithProtocol, auth);

      for (ArtifactsCollection artifactsCollection : myArtifactsCollections) {
        final int numOfUploadedFiles = upload(artifactsCollection.getFilePathMap(), destinationDir);
        myLogger.message("Uploaded [" + numOfUploadedFiles + "] files for [" + artifactsCollection.getSourcePath() + "] pattern");
      }
      return BuildFinishedStatus.FINISHED_SUCCESS;
    } catch (UploadInterruptedException e) {