changeset 266:643fa1236f4e

Fix file encoding * * * Fix line-endings
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Wed, 20 Jul 2011 12:04:08 +0400
parents 84119180bb1b
children 8f97c8ef1b67
files build.xml mercurial-agent/src/META-INF/build-agent-plugin-mercurial.xml mercurial-agent/src/build-agent-plugin.xml mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialAgentSideVcsSupport.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/PathUtil.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BranchesCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSet.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSetRevision.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangedFilesCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CloneCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/IdentifyCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ModifiedFile.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PullCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PushCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/StatusCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/TagCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/UpdateCommand.java mercurial-server/src/META-INF/build-server-plugin-mercurial.xml mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutTest.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/BaseMercurialTestCase.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/LocalRepositoryUtil.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SettingsTest.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommandTestCase.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommandTest.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PushCommandTest.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/StatusCommandTest.java mercurial-tests/src/testng.xml
diffstat 33 files changed, 2696 insertions(+), 2696 deletions(-) [+]
line wrap: on
line diff
--- a/build.xml	Thu Jul 07 14:11:32 2011 +0400
+++ b/build.xml	Wed Jul 20 12:04:08 2011 +0400
@@ -1,72 +1,72 @@
-<project name="Mercurial VCS Support" default="dist" basedir=".">
-  <property file="mercurial.properties"/>
-  <import file="mercurial.xml"/>
-
-  <property name="distPath" value="${basedir}/dist"/>
-
-  <property name="plugin.name" value="mercurial"/>
-
-  <property name="build.number" value=""/>
-  <tstamp>
-    <format property="timestamp" pattern="yyyyMMddhhmmss"/>
-  </tstamp>
-  <property name="snapshot.build.number" value="SNAPSHOT-${timestamp}"/>
-  <property name="build.vcs.number" value=""/>
-
-  <condition property="plugin.version" value="${snapshot.build.number}" else="${build.number}">
-    <matches pattern="snapshot-.*" string="${build.number}" casesensitive="false"/>
-  </condition>
-
-  <import file="teamcity-common.xml"/>
-
-  <target name="package" depends="define.version">
-    <package.teamcity.plugin name="${plugin.name}"
-                             server.output="${mercurial-server.output.dir}"
-                             agent.output="${mercurial-agent.output.dir}"
-                             common.output="${mercurial-common.output.dir}"
-                             plugin.descriptor.file="${basedir}/teamcity-plugin.xml"
-                             plugin.version="${plugin.version}"/>
-  </target>
-
-  <target name="define.version" depends="define.version.if.under.teamcity">
-    <tstamp>
-      <format property="current.time" pattern="yyyyMMddHHmm"/>
-    </tstamp>
-    <property name="plugin.version" value="SNAPSHOT-${current.time}"/>
-  </target>
-
-  <target name="define.version.if.under.teamcity" if="build.number">
-    <property name="plugin.version" value="${build.number}"/>
-  </target>
-
-  <target name="dist" depends="check.teamcitydistribution,all,package"/>
-
-  <target name="deploy" depends="dist">
-    <deploy.teamcity.plugin name="${plugin.name}"/>
-  </target>
-
-  <taskdef name="testng" classname="org.testng.TestNGAntTask" classpath="${basedir}/mercurial-tests/lib/testng-5.7-jdk15.jar"/>
-
-  <path id="tests_classpath">
-    <pathelement location="${agent.home.dir}/lib/runtime-util.jar"/>
-    <pathelement location="${agent.home.dir}/lib/buildServerRuntimeUtil.jar"/>
-    <path refid="mercurial-tests.runtime.module.classpath"/>
-  </path>
-
-  <target name="run-tests" depends="clean, init, compile.module.mercurial-tests">
-    <property name="suspend" value="n"/>
-
-    <testng haltonfailure="no" failureProperty="failure_found" listener="org.testng.reporters.TestHTMLReporter"
-            outputdir="${basedir}/test-output" classpathref="tests_classpath" dumpcommand="true" workingDir="${basedir}">
-
-      <jvmarg value="-ea"/>
-      <!--<jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=${suspend},address=5555"/>-->
-
-      <sysproperty key="java.awt.headless" value="true"/>
-
-      <xmlfileset dir="${basedir}/mercurial-tests/src">
-        <include name="testng.xml"/>
-      </xmlfileset>
-    </testng>
-  </target>
-</project>
+<project name="Mercurial VCS Support" default="dist" basedir=".">
+  <property file="mercurial.properties"/>
+  <import file="mercurial.xml"/>
+
+  <property name="distPath" value="${basedir}/dist"/>
+
+  <property name="plugin.name" value="mercurial"/>
+
+  <property name="build.number" value=""/>
+  <tstamp>
+    <format property="timestamp" pattern="yyyyMMddhhmmss"/>
+  </tstamp>
+  <property name="snapshot.build.number" value="SNAPSHOT-${timestamp}"/>
+  <property name="build.vcs.number" value=""/>
+
+  <condition property="plugin.version" value="${snapshot.build.number}" else="${build.number}">
+    <matches pattern="snapshot-.*" string="${build.number}" casesensitive="false"/>
+  </condition>
+
+  <import file="teamcity-common.xml"/>
+
+  <target name="package" depends="define.version">
+    <package.teamcity.plugin name="${plugin.name}"
+                             server.output="${mercurial-server.output.dir}"
+                             agent.output="${mercurial-agent.output.dir}"
+                             common.output="${mercurial-common.output.dir}"
+                             plugin.descriptor.file="${basedir}/teamcity-plugin.xml"
+                             plugin.version="${plugin.version}"/>
+  </target>
+
+  <target name="define.version" depends="define.version.if.under.teamcity">
+    <tstamp>
+      <format property="current.time" pattern="yyyyMMddHHmm"/>
+    </tstamp>
+    <property name="plugin.version" value="SNAPSHOT-${current.time}"/>
+  </target>
+
+  <target name="define.version.if.under.teamcity" if="build.number">
+    <property name="plugin.version" value="${build.number}"/>
+  </target>
+
+  <target name="dist" depends="check.teamcitydistribution,all,package"/>
+
+  <target name="deploy" depends="dist">
+    <deploy.teamcity.plugin name="${plugin.name}"/>
+  </target>
+
+  <taskdef name="testng" classname="org.testng.TestNGAntTask" classpath="${basedir}/mercurial-tests/lib/testng-5.7-jdk15.jar"/>
+
+  <path id="tests_classpath">
+    <pathelement location="${agent.home.dir}/lib/runtime-util.jar"/>
+    <pathelement location="${agent.home.dir}/lib/buildServerRuntimeUtil.jar"/>
+    <path refid="mercurial-tests.runtime.module.classpath"/>
+  </path>
+
+  <target name="run-tests" depends="clean, init, compile.module.mercurial-tests">
+    <property name="suspend" value="n"/>
+
+    <testng haltonfailure="no" failureProperty="failure_found" listener="org.testng.reporters.TestHTMLReporter"
+            outputdir="${basedir}/test-output" classpathref="tests_classpath" dumpcommand="true" workingDir="${basedir}">
+
+      <jvmarg value="-ea"/>
+      <!--<jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=${suspend},address=5555"/>-->
+
+      <sysproperty key="java.awt.headless" value="true"/>
+
+      <xmlfileset dir="${basedir}/mercurial-tests/src">
+        <include name="testng.xml"/>
+      </xmlfileset>
+    </testng>
+  </target>
+</project>
--- a/mercurial-agent/src/META-INF/build-agent-plugin-mercurial.xml	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-agent/src/META-INF/build-agent-plugin-mercurial.xml	Wed Jul 20 12:04:08 2011 +0400
@@ -1,6 +1,6 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
-
-<beans default-autowire="constructor">
-  <bean id="mercurialAgent" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialAgentSideVcsSupport" />
-</beans>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
+
+<beans default-autowire="constructor">
+  <bean id="mercurialAgent" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialAgentSideVcsSupport" />
+</beans>
--- a/mercurial-agent/src/build-agent-plugin.xml	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-agent/src/build-agent-plugin.xml	Wed Jul 20 12:04:08 2011 +0400
@@ -1,7 +1,7 @@
-<!--
-PicoContainer configuration for old fashioned TeamCity agent plugins.
-In TeamCity 4.0 Spring configuration must be created instead.
--->
-<container>
-  <component class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialAgentSideVcsSupport" />
+<!--
+PicoContainer configuration for old fashioned TeamCity agent plugins.
+In TeamCity 4.0 Spring configuration must be created instead.
+-->
+<container>
+  <component class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialAgentSideVcsSupport" />
 </container>
\ No newline at end of file
--- a/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialAgentSideVcsSupport.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialAgentSideVcsSupport.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,161 +1,161 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
-
-import jetbrains.buildServer.agent.AgentRunningBuild;
-import jetbrains.buildServer.agent.BuildAgentConfiguration;
-import jetbrains.buildServer.agent.BuildProgressLogger;
-import jetbrains.buildServer.agent.vcs.AgentVcsSupport;
-import jetbrains.buildServer.agent.vcs.IncludeRuleUpdater;
-import jetbrains.buildServer.agent.vcs.UpdateByIncludeRules2;
-import jetbrains.buildServer.agent.vcs.UpdatePolicy;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.*;
-import jetbrains.buildServer.util.FileUtil;
-import jetbrains.buildServer.vcs.CheckoutRules;
-import jetbrains.buildServer.vcs.IncludeRule;
-import jetbrains.buildServer.vcs.VcsException;
-import jetbrains.buildServer.vcs.VcsRoot;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.io.IOException;
-
-public class MercurialAgentSideVcsSupport extends AgentVcsSupport implements UpdateByIncludeRules2 {
-
-  private final MirrorManager myMirrorManager;
-
-  public MercurialAgentSideVcsSupport(BuildAgentConfiguration agentConfiguration) {
-    myMirrorManager = new MirrorManager(agentConfiguration.getCacheDirectory("mercurial"));
-  }
-
-  public IncludeRuleUpdater getUpdater(@NotNull final VcsRoot vcsRoot, @NotNull final CheckoutRules checkoutRules, @NotNull final String toVersion, @NotNull final File checkoutDirectory, @NotNull final AgentRunningBuild build, boolean cleanCheckoutRequested) throws VcsException {
-    final BuildProgressLogger logger = build.getBuildLogger();
-    final boolean useLocalMirrors = isUseLocalMirrors(build);
-    return new IncludeRuleUpdater() {
-      public void process(@NotNull final IncludeRule includeRule, @NotNull final File workingDir) throws VcsException {
-        checkRuleIsValid(includeRule);
-        Settings settings = new Settings(vcsRoot);
-        if (useLocalMirrors) {
-          updateLocalMirror(vcsRoot, logger);
-        }
-        updateRepository(workingDir, settings, logger, useLocalMirrors);
-        updateWorkingDir(settings, workingDir, toVersion, logger);
-      }
-
-      public void dispose() throws VcsException {
-      }
-    };
-  }
-
-  @NotNull
-  @Override
-  public String getName() {
-    return Constants.VCS_NAME;
-  }
-
-  @NotNull
-  @Override
-  public UpdatePolicy getUpdatePolicy() {
-    return this;
-  }
-
-  private boolean isUseLocalMirrors(AgentRunningBuild build) {
-    String value = build.getSharedConfigParameters().get("teamcity.hg.use.local.mirrors");
-    return "true".equals(value);
-  }
-
-  private void initRepository(File workingDir, Settings settings, BuildProgressLogger logger, boolean useLocalMirrors) throws VcsException {
-    try {
-      logger.message("Init repository at " + workingDir.getAbsolutePath());
-      String defaultPullUrl = getDefaultPullUrl(settings, useLocalMirrors);
-      new Init(settings, workingDir, defaultPullUrl).execute();
-    } catch (IOException e) {
-      throw new VcsException("Error while initializing repository at " + workingDir.getAbsolutePath(), e);
-    }
-  }
-
-  private void updateRepository(File workingDir, Settings settings, BuildProgressLogger logger, boolean useLocalMirrors) throws VcsException {
-    if (!Settings.isValidRepository(workingDir)) {
-      initRepository(workingDir, settings, logger, useLocalMirrors);
-    } else {
-      ensureUseRightRepository(workingDir, settings, logger, useLocalMirrors);
-    }
-    logger.message("Start pulling changes");
-    new PullCommand(settings, workingDir).execute();
-    logger.message("Changes successfully pulled");
-  }
-
-  private void ensureUseRightRepository(File workingDir, Settings settings, BuildProgressLogger logger, boolean useLocalMirrors) throws VcsException {
-    boolean clonedFromWrongRepository = useLocalMirrors && !isClonedFromLocalMirror(settings, workingDir)
-                                     || !useLocalMirrors && isClonedFromLocalMirror(settings, workingDir);
-
-    if (clonedFromWrongRepository) {
-      String rightRepository = useLocalMirrors ? "local mirror" : "remote repository";
-      String wrongRepository = useLocalMirrors ? "remote repository" : "local mirror";
-      logger.message("Repository in working directory is cloned from " + wrongRepository + ", clone it from " + rightRepository);
-      FileUtil.delete(workingDir);
-      initRepository(workingDir, settings, logger, useLocalMirrors);
-    }
-  }
-
-  private void updateLocalMirror(VcsRoot root, BuildProgressLogger logger) throws VcsException {
-    Settings settings = new Settings(root);
-    File mirrorDir = myMirrorManager.getMirrorDir(settings.getRepositoryUrl());
-    if (!Settings.isValidRepository(mirrorDir)) {
-      initRepository(mirrorDir, settings, logger, false);
-    }
-    logger.message("Start pulling changes to local mirror at " + mirrorDir);
-    new PullCommand(settings, mirrorDir).execute();
-    logger.message("Local mirror changes successfully pulled");
-  }
-
-  private void updateWorkingDir(final Settings settings, File workingDir, final String version, final BuildProgressLogger logger) throws VcsException {
-    logger.message("Updating working directory from the local repository copy");
-    UpdateCommand uc = new UpdateCommand(settings, workingDir);
-    ChangeSet cs = new ChangeSet(version);
-    uc.setToId(cs.getId());
-    uc.execute();
-    logger.message("Working directory updated successfully");
-  }
-
-  private String getDefaultPullUrl(Settings settings, boolean useLocalMirror) throws IOException {
-    if (useLocalMirror) {
-      File mirrorDir = myMirrorManager.getMirrorDir(settings.getRepositoryUrl());
-      return mirrorDir.getCanonicalPath();
-    } else {
-      return settings.getRepositoryUrl();
-    }
-  }
-
-  private void checkRuleIsValid(IncludeRule includeRule) throws VcsException {
-    if (includeRule.getTo() != null && includeRule.getTo().length() > 0) {
-      if (!".".equals(includeRule.getFrom()) && includeRule.getFrom().length() != 0) {
-        throw new VcsException("Invalid include rule: " + includeRule.toString() + ", Mercurial plugin supports mapping of the form: +:.=>dir only.");
-      }
-    }
-  }
-
-  public boolean isClonedFromLocalMirror(Settings settings, File workingDir) {
-    try {
-      File mirrorDir = myMirrorManager.getMirrorDir(settings.getRepositoryUrl());
-      File hgrc = new File(workingDir, ".hg" + File.separator + "hgrc");
-      String config = FileUtil.readText(hgrc);
-      return config.contains("default = " + mirrorDir.getCanonicalPath());
-    } catch (Exception e) {
-      return false;
-    }
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import jetbrains.buildServer.agent.AgentRunningBuild;
+import jetbrains.buildServer.agent.BuildAgentConfiguration;
+import jetbrains.buildServer.agent.BuildProgressLogger;
+import jetbrains.buildServer.agent.vcs.AgentVcsSupport;
+import jetbrains.buildServer.agent.vcs.IncludeRuleUpdater;
+import jetbrains.buildServer.agent.vcs.UpdateByIncludeRules2;
+import jetbrains.buildServer.agent.vcs.UpdatePolicy;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.*;
+import jetbrains.buildServer.util.FileUtil;
+import jetbrains.buildServer.vcs.CheckoutRules;
+import jetbrains.buildServer.vcs.IncludeRule;
+import jetbrains.buildServer.vcs.VcsException;
+import jetbrains.buildServer.vcs.VcsRoot;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+
+public class MercurialAgentSideVcsSupport extends AgentVcsSupport implements UpdateByIncludeRules2 {
+
+  private final MirrorManager myMirrorManager;
+
+  public MercurialAgentSideVcsSupport(BuildAgentConfiguration agentConfiguration) {
+    myMirrorManager = new MirrorManager(agentConfiguration.getCacheDirectory("mercurial"));
+  }
+
+  public IncludeRuleUpdater getUpdater(@NotNull final VcsRoot vcsRoot, @NotNull final CheckoutRules checkoutRules, @NotNull final String toVersion, @NotNull final File checkoutDirectory, @NotNull final AgentRunningBuild build, boolean cleanCheckoutRequested) throws VcsException {
+    final BuildProgressLogger logger = build.getBuildLogger();
+    final boolean useLocalMirrors = isUseLocalMirrors(build);
+    return new IncludeRuleUpdater() {
+      public void process(@NotNull final IncludeRule includeRule, @NotNull final File workingDir) throws VcsException {
+        checkRuleIsValid(includeRule);
+        Settings settings = new Settings(vcsRoot);
+        if (useLocalMirrors) {
+          updateLocalMirror(vcsRoot, logger);
+        }
+        updateRepository(workingDir, settings, logger, useLocalMirrors);
+        updateWorkingDir(settings, workingDir, toVersion, logger);
+      }
+
+      public void dispose() throws VcsException {
+      }
+    };
+  }
+
+  @NotNull
+  @Override
+  public String getName() {
+    return Constants.VCS_NAME;
+  }
+
+  @NotNull
+  @Override
+  public UpdatePolicy getUpdatePolicy() {
+    return this;
+  }
+
+  private boolean isUseLocalMirrors(AgentRunningBuild build) {
+    String value = build.getSharedConfigParameters().get("teamcity.hg.use.local.mirrors");
+    return "true".equals(value);
+  }
+
+  private void initRepository(File workingDir, Settings settings, BuildProgressLogger logger, boolean useLocalMirrors) throws VcsException {
+    try {
+      logger.message("Init repository at " + workingDir.getAbsolutePath());
+      String defaultPullUrl = getDefaultPullUrl(settings, useLocalMirrors);
+      new Init(settings, workingDir, defaultPullUrl).execute();
+    } catch (IOException e) {
+      throw new VcsException("Error while initializing repository at " + workingDir.getAbsolutePath(), e);
+    }
+  }
+
+  private void updateRepository(File workingDir, Settings settings, BuildProgressLogger logger, boolean useLocalMirrors) throws VcsException {
+    if (!Settings.isValidRepository(workingDir)) {
+      initRepository(workingDir, settings, logger, useLocalMirrors);
+    } else {
+      ensureUseRightRepository(workingDir, settings, logger, useLocalMirrors);
+    }
+    logger.message("Start pulling changes");
+    new PullCommand(settings, workingDir).execute();
+    logger.message("Changes successfully pulled");
+  }
+
+  private void ensureUseRightRepository(File workingDir, Settings settings, BuildProgressLogger logger, boolean useLocalMirrors) throws VcsException {
+    boolean clonedFromWrongRepository = useLocalMirrors && !isClonedFromLocalMirror(settings, workingDir)
+                                     || !useLocalMirrors && isClonedFromLocalMirror(settings, workingDir);
+
+    if (clonedFromWrongRepository) {
+      String rightRepository = useLocalMirrors ? "local mirror" : "remote repository";
+      String wrongRepository = useLocalMirrors ? "remote repository" : "local mirror";
+      logger.message("Repository in working directory is cloned from " + wrongRepository + ", clone it from " + rightRepository);
+      FileUtil.delete(workingDir);
+      initRepository(workingDir, settings, logger, useLocalMirrors);
+    }
+  }
+
+  private void updateLocalMirror(VcsRoot root, BuildProgressLogger logger) throws VcsException {
+    Settings settings = new Settings(root);
+    File mirrorDir = myMirrorManager.getMirrorDir(settings.getRepositoryUrl());
+    if (!Settings.isValidRepository(mirrorDir)) {
+      initRepository(mirrorDir, settings, logger, false);
+    }
+    logger.message("Start pulling changes to local mirror at " + mirrorDir);
+    new PullCommand(settings, mirrorDir).execute();
+    logger.message("Local mirror changes successfully pulled");
+  }
+
+  private void updateWorkingDir(final Settings settings, File workingDir, final String version, final BuildProgressLogger logger) throws VcsException {
+    logger.message("Updating working directory from the local repository copy");
+    UpdateCommand uc = new UpdateCommand(settings, workingDir);
+    ChangeSet cs = new ChangeSet(version);
+    uc.setToId(cs.getId());
+    uc.execute();
+    logger.message("Working directory updated successfully");
+  }
+
+  private String getDefaultPullUrl(Settings settings, boolean useLocalMirror) throws IOException {
+    if (useLocalMirror) {
+      File mirrorDir = myMirrorManager.getMirrorDir(settings.getRepositoryUrl());
+      return mirrorDir.getCanonicalPath();
+    } else {
+      return settings.getRepositoryUrl();
+    }
+  }
+
+  private void checkRuleIsValid(IncludeRule includeRule) throws VcsException {
+    if (includeRule.getTo() != null && includeRule.getTo().length() > 0) {
+      if (!".".equals(includeRule.getFrom()) && includeRule.getFrom().length() != 0) {
+        throw new VcsException("Invalid include rule: " + includeRule.toString() + ", Mercurial plugin supports mapping of the form: +:.=>dir only.");
+      }
+    }
+  }
+
+  public boolean isClonedFromLocalMirror(Settings settings, File workingDir) {
+    try {
+      File mirrorDir = myMirrorManager.getMirrorDir(settings.getRepositoryUrl());
+      File hgrc = new File(workingDir, ".hg" + File.separator + "hgrc");
+      String config = FileUtil.readText(hgrc);
+      return config.contains("default = " + mirrorDir.getCanonicalPath());
+    } catch (Exception e) {
+      return false;
+    }
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,30 +1,30 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
-
-import jetbrains.buildServer.vcs.VcsRoot;
-
-public interface Constants {
-  String VCS_NAME = "mercurial";
-  String REPOSITORY_PROP = "repositoryPath";
-  String BRANCH_NAME_PROP = "branchName";
-  String HG_COMMAND_PATH_PROP = "hgCommandPath";
-  String HG_PATH_ENV = "TEAMCITY_HG_PATH";
-  String SERVER_CLONE_PATH_PROP = "serverClonePath";
-  String USERNAME = "username";
-  String PASSWORD = VcsRoot.SECURE_PROPERTY_PREFIX + "password";
-  String UNCOMPRESSED_TRANSFER = "uncompressedTransfer";
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import jetbrains.buildServer.vcs.VcsRoot;
+
+public interface Constants {
+  String VCS_NAME = "mercurial";
+  String REPOSITORY_PROP = "repositoryPath";
+  String BRANCH_NAME_PROP = "branchName";
+  String HG_COMMAND_PATH_PROP = "hgCommandPath";
+  String HG_PATH_ENV = "TEAMCITY_HG_PATH";
+  String SERVER_CLONE_PATH_PROP = "serverClonePath";
+  String USERNAME = "username";
+  String PASSWORD = VcsRoot.SECURE_PROPERTY_PREFIX + "password";
+  String UNCOMPRESSED_TRANSFER = "uncompressedTransfer";
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/PathUtil.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/PathUtil.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,37 +1,37 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.io.IOException;
-
-public class PathUtil {
-  @NotNull
-  public static String normalizeSeparator(@NotNull String repPath) {
-    return repPath.replace('\\', '/');
-  }
-
-  @NotNull
-  public static File getCanonicalFile(@NotNull File file) {
-    try {
-      return file.getCanonicalFile();
-    } catch (IOException e) {
-      return file.getAbsoluteFile();
-    }
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+
+public class PathUtil {
+  @NotNull
+  public static String normalizeSeparator(@NotNull String repPath) {
+    return repPath.replace('\\', '/');
+  }
+
+  @NotNull
+  public static File getCanonicalFile(@NotNull File file) {
+    try {
+      return file.getCanonicalFile();
+    } catch (IOException e) {
+      return file.getAbsoluteFile();
+    }
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,134 +1,134 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import com.intellij.openapi.util.SystemInfo;
-import jetbrains.buildServer.ExecResult;
-import jetbrains.buildServer.util.StringUtil;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * @author pavel
- */
-public class BaseCommand {
-  private Settings mySettings;
-  private String myWorkDirectory;
-
-  public BaseCommand(@NotNull final Settings settings, @NotNull File workingDir) {
-    mySettings = settings;
-    myWorkDirectory = workingDir.getAbsolutePath();
-  }
-
-
-  public Settings getSettings() {
-    return mySettings;
-  }
-
-  /**
-   * Sets new working directory, by default working directory is taken from the Settings#getLocalRepositoryDir
-   * @param workDirectory work dir
-   */
-  public void setWorkDirectory(final String workDirectory) {
-    myWorkDirectory = workDirectory;
-  }
-
-  public String getWorkDirectory() {
-    return myWorkDirectory;
-  }
-
-  protected GeneralCommandLine createCommandLine() {
-    GeneralCommandLine cli = createCL();
-    cli.setWorkDirectory(myWorkDirectory);
-    cli.setPassParentEnvs(true);
-    return cli;
-  }
-
-  protected GeneralCommandLine createCL() {
-    GeneralCommandLine cl = new EscapingCommandLineDecorator();
-    setupExecutable(cl);
-    return cl;
-  }
-
-  /**
-   * Escape its parameters
-   */
-  private static class EscapingCommandLineDecorator extends GeneralCommandLine {
-    @Override
-    public void addParameter(@NotNull String parameter) {
-      String escaped = escape(parameter);
-      super.addParameter(escaped);
-    }
-
-    private String escape(String s) {
-      return StringUtil.escapeQuotesIfWindows(s);
-    }
-  }
-
-  /**
-   * Since mercurial 1.7 on Windows the only file inside '<mercurial_install_dir>/bin' is 'hg.cmd' 
-   * which run hg.exe placed in the parent dir. GeneralCommandLine will not find hg.cmd, in the 
-   * case when $PATH contains <mercurial_install_dir>/bin and doesn't contain <mercurial_install_dir> 
-   * and hg executable is set to 'hg'. To fix it - run hg using windows shell which expand
-   * hg to hg.cmd correctly.
-   */
-  private void setupExecutable(GeneralCommandLine cli) {
-    if (SystemInfo.isWindows && getSettings().getHgCommandPath().equals("hg")) {
-      setupCmd(cli);
-    } else {
-      setupHg(cli);
-    }
-  }
-
-  private void setupCmd(GeneralCommandLine cli) {
-    cli.setExePath("cmd");
-    cli.addParameter("/c");
-    cli.addParameter("hg");
-  }
-
-  private void setupHg(GeneralCommandLine cli) {
-    cli.setExePath(getSettings().getHgCommandPath());
-  }
-
-  protected ExecResult runCommand(@NotNull GeneralCommandLine cli) throws VcsException {
-    return CommandUtil.runCommand(cli, getPrivateData());
-  }
-
-  protected ExecResult runCommand(@NotNull GeneralCommandLine cli, int executionTimeout) throws VcsException {
-    return CommandUtil.runCommand(cli, executionTimeout, getPrivateData());
-  }
-
-  protected void failIfNotEmptyStdErr(@NotNull GeneralCommandLine cli, @NotNull ExecResult res) throws VcsException {
-    if (!StringUtil.isEmpty(res.getStderr())) {
-      CommandUtil.commandFailed(cli.getCommandLineString(), res);
-    }
-  }
-
-  protected void failIfNonZeroExitCode(@NotNull GeneralCommandLine cli, @NotNull ExecResult res) throws VcsException {
-    if (res.getExitCode() != 0) {
-      CommandUtil.commandFailed(cli.getCommandLineString(), res);
-    }
-  }
-
-  public Set<String> getPrivateData() {
-    return Collections.singleton(mySettings.getPassword());
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.openapi.util.SystemInfo;
+import jetbrains.buildServer.ExecResult;
+import jetbrains.buildServer.util.StringUtil;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author pavel
+ */
+public class BaseCommand {
+  private Settings mySettings;
+  private String myWorkDirectory;
+
+  public BaseCommand(@NotNull final Settings settings, @NotNull File workingDir) {
+    mySettings = settings;
+    myWorkDirectory = workingDir.getAbsolutePath();
+  }
+
+
+  public Settings getSettings() {
+    return mySettings;
+  }
+
+  /**
+   * Sets new working directory, by default working directory is taken from the Settings#getLocalRepositoryDir
+   * @param workDirectory work dir
+   */
+  public void setWorkDirectory(final String workDirectory) {
+    myWorkDirectory = workDirectory;
+  }
+
+  public String getWorkDirectory() {
+    return myWorkDirectory;
+  }
+
+  protected GeneralCommandLine createCommandLine() {
+    GeneralCommandLine cli = createCL();
+    cli.setWorkDirectory(myWorkDirectory);
+    cli.setPassParentEnvs(true);
+    return cli;
+  }
+
+  protected GeneralCommandLine createCL() {
+    GeneralCommandLine cl = new EscapingCommandLineDecorator();
+    setupExecutable(cl);
+    return cl;
+  }
+
+  /**
+   * Escape its parameters
+   */
+  private static class EscapingCommandLineDecorator extends GeneralCommandLine {
+    @Override
+    public void addParameter(@NotNull String parameter) {
+      String escaped = escape(parameter);
+      super.addParameter(escaped);
+    }
+
+    private String escape(String s) {
+      return StringUtil.escapeQuotesIfWindows(s);
+    }
+  }
+
+  /**
+   * Since mercurial 1.7 on Windows the only file inside '<mercurial_install_dir>/bin' is 'hg.cmd' 
+   * which run hg.exe placed in the parent dir. GeneralCommandLine will not find hg.cmd, in the 
+   * case when $PATH contains <mercurial_install_dir>/bin and doesn't contain <mercurial_install_dir> 
+   * and hg executable is set to 'hg'. To fix it - run hg using windows shell which expand
+   * hg to hg.cmd correctly.
+   */
+  private void setupExecutable(GeneralCommandLine cli) {
+    if (SystemInfo.isWindows && getSettings().getHgCommandPath().equals("hg")) {
+      setupCmd(cli);
+    } else {
+      setupHg(cli);
+    }
+  }
+
+  private void setupCmd(GeneralCommandLine cli) {
+    cli.setExePath("cmd");
+    cli.addParameter("/c");
+    cli.addParameter("hg");
+  }
+
+  private void setupHg(GeneralCommandLine cli) {
+    cli.setExePath(getSettings().getHgCommandPath());
+  }
+
+  protected ExecResult runCommand(@NotNull GeneralCommandLine cli) throws VcsException {
+    return CommandUtil.runCommand(cli, getPrivateData());
+  }
+
+  protected ExecResult runCommand(@NotNull GeneralCommandLine cli, int executionTimeout) throws VcsException {
+    return CommandUtil.runCommand(cli, executionTimeout, getPrivateData());
+  }
+
+  protected void failIfNotEmptyStdErr(@NotNull GeneralCommandLine cli, @NotNull ExecResult res) throws VcsException {
+    if (!StringUtil.isEmpty(res.getStderr())) {
+      CommandUtil.commandFailed(cli.getCommandLineString(), res);
+    }
+  }
+
+  protected void failIfNonZeroExitCode(@NotNull GeneralCommandLine cli, @NotNull ExecResult res) throws VcsException {
+    if (res.getExitCode() != 0) {
+      CommandUtil.commandFailed(cli.getCommandLineString(), res);
+    }
+  }
+
+  public Set<String> getPrivateData() {
+    return Collections.singleton(mySettings.getPassword());
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BranchesCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BranchesCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,61 +1,61 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.ExecResult;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @author Pavel.Sher
- *         Date: 26.10.2008
- */
-public class BranchesCommand extends BaseCommand {
-
-  public BranchesCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-  }
-
-  /**
-   * Returns map of branch name to latest changeset in that branch
-   * @return see above
-   * @throws jetbrains.buildServer.vcs.VcsException if error occurs
-   */
-  public Map<String, ChangeSet> execute() throws VcsException {
-    GeneralCommandLine cli = createCommandLine();
-    cli.addParameter("branches");
-    ExecResult res = runCommand(cli);
-    String stdout = res.getStdout();
-    Map<String, ChangeSet> result = new HashMap<String, ChangeSet>();
-    Pattern branchPattern = Pattern.compile("(.*)[\\s]+([0-9]+:[A-Za-z0-9]+).*");
-    for (String line: stdout.split("[\r\n]+")) {
-      Matcher matcher = branchPattern.matcher(line);
-      if (matcher.matches()) {
-        String branchName = matcher.group(1).trim();
-        String changeId = matcher.group(2).trim();
-        result.put(branchName, new ChangeSet(changeId));
-      }
-    }
-    return result;
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.ExecResult;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Pavel.Sher
+ *         Date: 26.10.2008
+ */
+public class BranchesCommand extends BaseCommand {
+
+  public BranchesCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+  }
+
+  /**
+   * Returns map of branch name to latest changeset in that branch
+   * @return see above
+   * @throws jetbrains.buildServer.vcs.VcsException if error occurs
+   */
+  public Map<String, ChangeSet> execute() throws VcsException {
+    GeneralCommandLine cli = createCommandLine();
+    cli.addParameter("branches");
+    ExecResult res = runCommand(cli);
+    String stdout = res.getStdout();
+    Map<String, ChangeSet> result = new HashMap<String, ChangeSet>();
+    Pattern branchPattern = Pattern.compile("(.*)[\\s]+([0-9]+:[A-Za-z0-9]+).*");
+    for (String line: stdout.split("[\r\n]+")) {
+      Matcher matcher = branchPattern.matcher(line);
+      if (matcher.matches()) {
+        String branchName = matcher.group(1).trim();
+        String changeId = matcher.group(2).trim();
+        result.put(branchName, new ChangeSet(changeId));
+      }
+    }
+    return result;
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,83 +1,83 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.util.FileUtil;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-
-public class CatCommand extends BaseCommand {
-  private String myRevId;
-  private final static int MAX_CMD_LEN = 900;
-
-  public CatCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-  }
-
-  public void setRevId(final String revId) {
-    myRevId = revId;
-  }
-
-  public File execute(List<String> relPaths) throws VcsException {
-    File tempDir;
-    try {
-      tempDir = FileUtil.createTempDirectory("mercurial", "catresult");
-    } catch (IOException e) {
-      throw new VcsException("Unable to create temporary directory");
-    }
-    for (String path: relPaths) {
-      final File parentFile = new File(tempDir, path).getParentFile();
-      if (!parentFile.isDirectory() && !parentFile.mkdirs()) {
-        throw new VcsException("Failed to create directory: " + parentFile.getAbsolutePath());
-      }
-    }
-
-    Queue<String> paths = new LinkedList<String>(relPaths);
-    while (!paths.isEmpty()) {
-      GeneralCommandLine cli = createCommandLine(tempDir);
-      int cmdSize = cli.getCommandLineString().length();
-
-      do {
-        String path = paths.poll();
-        cli.addParameter(path);
-        cmdSize += path.length();
-      } while (cmdSize < MAX_CMD_LEN && !paths.isEmpty());
-
-      runCommand(cli);
-    }
-
-    return tempDir;
-  }
-
-  private GeneralCommandLine createCommandLine(final File tempDir) {
-    GeneralCommandLine cli = createCommandLine();
-    cli.addParameter("cat");
-    cli.addParameter("-o");
-    cli.addParameter(tempDir.getAbsolutePath() + File.separator + "%p");
-    if (myRevId != null) {
-      cli.addParameter("-r");
-      cli.addParameter(myRevId);
-    }
-    return cli;
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.util.FileUtil;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+public class CatCommand extends BaseCommand {
+  private String myRevId;
+  private final static int MAX_CMD_LEN = 900;
+
+  public CatCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+  }
+
+  public void setRevId(final String revId) {
+    myRevId = revId;
+  }
+
+  public File execute(List<String> relPaths) throws VcsException {
+    File tempDir;
+    try {
+      tempDir = FileUtil.createTempDirectory("mercurial", "catresult");
+    } catch (IOException e) {
+      throw new VcsException("Unable to create temporary directory");
+    }
+    for (String path: relPaths) {
+      final File parentFile = new File(tempDir, path).getParentFile();
+      if (!parentFile.isDirectory() && !parentFile.mkdirs()) {
+        throw new VcsException("Failed to create directory: " + parentFile.getAbsolutePath());
+      }
+    }
+
+    Queue<String> paths = new LinkedList<String>(relPaths);
+    while (!paths.isEmpty()) {
+      GeneralCommandLine cli = createCommandLine(tempDir);
+      int cmdSize = cli.getCommandLineString().length();
+
+      do {
+        String path = paths.poll();
+        cli.addParameter(path);
+        cmdSize += path.length();
+      } while (cmdSize < MAX_CMD_LEN && !paths.isEmpty());
+
+      runCommand(cli);
+    }
+
+    return tempDir;
+  }
+
+  private GeneralCommandLine createCommandLine(final File tempDir) {
+    GeneralCommandLine cli = createCommandLine();
+    cli.addParameter("cat");
+    cli.addParameter("-o");
+    cli.addParameter(tempDir.getAbsolutePath() + File.separator + "%p");
+    if (myRevId != null) {
+      cli.addParameter("-r");
+      cli.addParameter(myRevId);
+    }
+    return cli;
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSet.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSet.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,121 +1,121 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-/**
- * Represents Mercurial change set
- */
-public class ChangeSet extends ChangeSetRevision {
-  @NotNull private String myUser;
-  @NotNull private Date myTimestamp;
-  private String myDescription;
-  private boolean myContainsFiles;
-  private List<ChangeSetRevision> myParents;
-
-  public ChangeSet(final int revNumber, @NotNull final String id) {
-    super(revNumber, id);
-  }
-
-  /**
-   * Constructor for version in the form revnum:changeset_id or just changeset_id (in this case rev number is set to -1)
-   * @param fullVersion full changeset version as reported by hg log command
-   */
-  public ChangeSet(@NotNull final String fullVersion) {
-    super(fullVersion);
-  }
-
-  public void setUser(@NotNull final String user) {
-    myUser = user;
-  }
-
-  public void setTimestamp(@NotNull final Date timestamp) {
-    myTimestamp = timestamp;
-  }
-
-  public void setDescription(final String description) {
-    myDescription = description;
-  }
-
-  public void setContainsFiles(final boolean containsFiles) {
-    myContainsFiles = containsFiles;
-  }
-
-  public void addParent(@NotNull ChangeSetRevision rev) {
-    if (myParents == null) {
-      myParents = new ArrayList<ChangeSetRevision>();
-    }
-    myParents.add(rev);
-  }
-
-  /**
-   * Returns user who made changeset
-   * @return user who made changeset
-   */
-  @NotNull
-  public String getUser() {
-    return myUser;
-  }
-
-  /**
-   * Returns changeset timestamp
-   * @return changeset timestamp
-   */
-  @NotNull
-  public Date getTimestamp() {
-    return myTimestamp;
-  }
-
-  /**
-   * Returns changeset summary specified by user
-   * @return changeset summary
-   */
-  public String getDescription() {
-    return myDescription;
-  }
-
-  /**
-   * Returns parrents of this change set, or null if there were no parents.
-   * @return see above
-   */
-  @Nullable
-  public List<ChangeSetRevision> getParents() {
-    return myParents;
-  }
-
-  /**
-   * Returns true if this change has changed files
-   * @return see above
-   */
-  public boolean containsFiles() {
-    return myContainsFiles;
-  }
-
-
-  /**
-   * Check if changeset is initial changeset (has no parents)
-   * @return true if changeset is initial changeset
-   */
-  public boolean isInitial() {
-    return getParents() == null;
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Represents Mercurial change set
+ */
+public class ChangeSet extends ChangeSetRevision {
+  @NotNull private String myUser;
+  @NotNull private Date myTimestamp;
+  private String myDescription;
+  private boolean myContainsFiles;
+  private List<ChangeSetRevision> myParents;
+
+  public ChangeSet(final int revNumber, @NotNull final String id) {
+    super(revNumber, id);
+  }
+
+  /**
+   * Constructor for version in the form revnum:changeset_id or just changeset_id (in this case rev number is set to -1)
+   * @param fullVersion full changeset version as reported by hg log command
+   */
+  public ChangeSet(@NotNull final String fullVersion) {
+    super(fullVersion);
+  }
+
+  public void setUser(@NotNull final String user) {
+    myUser = user;
+  }
+
+  public void setTimestamp(@NotNull final Date timestamp) {
+    myTimestamp = timestamp;
+  }
+
+  public void setDescription(final String description) {
+    myDescription = description;
+  }
+
+  public void setContainsFiles(final boolean containsFiles) {
+    myContainsFiles = containsFiles;
+  }
+
+  public void addParent(@NotNull ChangeSetRevision rev) {
+    if (myParents == null) {
+      myParents = new ArrayList<ChangeSetRevision>();
+    }
+    myParents.add(rev);
+  }
+
+  /**
+   * Returns user who made changeset
+   * @return user who made changeset
+   */
+  @NotNull
+  public String getUser() {
+    return myUser;
+  }
+
+  /**
+   * Returns changeset timestamp
+   * @return changeset timestamp
+   */
+  @NotNull
+  public Date getTimestamp() {
+    return myTimestamp;
+  }
+
+  /**
+   * Returns changeset summary specified by user
+   * @return changeset summary
+   */
+  public String getDescription() {
+    return myDescription;
+  }
+
+  /**
+   * Returns parrents of this change set, or null if there were no parents.
+   * @return see above
+   */
+  @Nullable
+  public List<ChangeSetRevision> getParents() {
+    return myParents;
+  }
+
+  /**
+   * Returns true if this change has changed files
+   * @return see above
+   */
+  public boolean containsFiles() {
+    return myContainsFiles;
+  }
+
+
+  /**
+   * Check if changeset is initial changeset (has no parents)
+   * @return true if changeset is initial changeset
+   */
+  public boolean isInitial() {
+    return getParents() == null;
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSetRevision.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSetRevision.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,99 +1,99 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author Pavel.Sher
- */
-public class ChangeSetRevision {
-  private final int myRevNumber;
-  @NotNull
-  private final String myId;
-
-  public ChangeSetRevision(final int revNumber, @NotNull final String id) {
-    myRevNumber = revNumber;
-    myId = id;
-  }
-
-  /**
-   * Constructor for version in the form revnum:changeset_id or just changeset_id (in this case rev number is set to -1)
-   * @param fullVersion full changeset version as reported by hg log command
-   */
-  public ChangeSetRevision(@NotNull final String fullVersion) {
-    try {
-      int colon = fullVersion.indexOf(":");
-      if (colon != -1) {
-        myRevNumber = Integer.parseInt(fullVersion.substring(0, colon));
-        myId = fullVersion.substring(colon+1);
-      } else {
-        myRevNumber = -1;
-        myId = fullVersion;
-      }
-    } catch (Throwable e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  /**
-   * Returns changeset revision id
-   * @return changeset revision id
-   */
-  @NotNull
-  public String getId() {
-    return myId;
-  }
-
-  /**
-   * Returns changeset revision number
-   * @return changeset revision number
-   */
-  public int getRevNumber() {
-    return myRevNumber;
-  }
-
-  /**
-   * Returns full changeset version as reported by hg log command: revnum:revid
-   * @return full changeset version as reported by hg log
-   */
-  @NotNull
-  public String getFullVersion() {
-    return myRevNumber + ":" + myId;
-  }
-
-  @Override
-  public boolean equals(final Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    final ChangeSetRevision that = (ChangeSetRevision) o;
-
-    return myRevNumber == that.myRevNumber && myId.equals(that.myId);
-  }
-
-  @Override
-  public int hashCode() {
-    int result = myRevNumber;
-    result = 31 * result + myId.hashCode();
-    return result;
-  }
-
-  @Override
-  public String toString() {
-    return "change:" + myId;
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Pavel.Sher
+ */
+public class ChangeSetRevision {
+  private final int myRevNumber;
+  @NotNull
+  private final String myId;
+
+  public ChangeSetRevision(final int revNumber, @NotNull final String id) {
+    myRevNumber = revNumber;
+    myId = id;
+  }
+
+  /**
+   * Constructor for version in the form revnum:changeset_id or just changeset_id (in this case rev number is set to -1)
+   * @param fullVersion full changeset version as reported by hg log command
+   */
+  public ChangeSetRevision(@NotNull final String fullVersion) {
+    try {
+      int colon = fullVersion.indexOf(":");
+      if (colon != -1) {
+        myRevNumber = Integer.parseInt(fullVersion.substring(0, colon));
+        myId = fullVersion.substring(colon+1);
+      } else {
+        myRevNumber = -1;
+        myId = fullVersion;
+      }
+    } catch (Throwable e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+
+  /**
+   * Returns changeset revision id
+   * @return changeset revision id
+   */
+  @NotNull
+  public String getId() {
+    return myId;
+  }
+
+  /**
+   * Returns changeset revision number
+   * @return changeset revision number
+   */
+  public int getRevNumber() {
+    return myRevNumber;
+  }
+
+  /**
+   * Returns full changeset version as reported by hg log command: revnum:revid
+   * @return full changeset version as reported by hg log
+   */
+  @NotNull
+  public String getFullVersion() {
+    return myRevNumber + ":" + myId;
+  }
+
+  @Override
+  public boolean equals(final Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    final ChangeSetRevision that = (ChangeSetRevision) o;
+
+    return myRevNumber == that.myRevNumber && myId.equals(that.myId);
+  }
+
+  @Override
+  public int hashCode() {
+    int result = myRevNumber;
+    result = 31 * result + myId.hashCode();
+    return result;
+  }
+
+  @Override
+  public String toString() {
+    return "change:" + myId;
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangedFilesCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangedFilesCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,76 +1,76 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.ExecResult;
-import jetbrains.buildServer.util.FileUtil;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-/**
- * @author Pavel.Sher
- */
-public class ChangedFilesCommand extends BaseCommand {
-  private String myRevId;
-
-  public ChangedFilesCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-  }
-
-  public void setRevId(@NotNull final String revId) {
-    myRevId = revId;
-  }
-
-  public List<ModifiedFile> execute() throws VcsException {
-    File styleFile;
-    try {
-      styleFile = getStyleFile();
-    } catch (IOException e) {
-      throw new VcsException("Unable to create style file: " + e.toString(), e);
-    }
-    try {
-      GeneralCommandLine cli = createCommandLine();
-      cli.addParameter("log");
-      cli.addParameter("-r");
-      cli.addParameter(myRevId + ":" + myRevId);
-      cli.addParameter("--style=" + styleFile.getAbsolutePath());
-
-      ExecResult res = runCommand(cli);
-      return parseFiles(res.getStdout());
-    } finally {
-      FileUtil.delete(styleFile);
-    }
-  }
-
-  private File getStyleFile() throws IOException {
-    File styleFile = FileUtil.createTempFile("hg", "style");
-    FileUtil.writeFile(styleFile,
-            "changeset = \"{file_mods}{file_adds}{file_dels}\"\n" +
-            "file_add = \"A {file_add}\\n\"\n" +
-            "file_del = \"R {file_del}\\n\"\n" +
-            "file_mod = \"M {file_mod}\\n\"");
-    return styleFile;
-  }
-
-  private List<ModifiedFile> parseFiles(final String stdout) {
-    return StatusCommand.parseFiles(stdout);
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.ExecResult;
+import jetbrains.buildServer.util.FileUtil;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @author Pavel.Sher
+ */
+public class ChangedFilesCommand extends BaseCommand {
+  private String myRevId;
+
+  public ChangedFilesCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+  }
+
+  public void setRevId(@NotNull final String revId) {
+    myRevId = revId;
+  }
+
+  public List<ModifiedFile> execute() throws VcsException {
+    File styleFile;
+    try {
+      styleFile = getStyleFile();
+    } catch (IOException e) {
+      throw new VcsException("Unable to create style file: " + e.toString(), e);
+    }
+    try {
+      GeneralCommandLine cli = createCommandLine();
+      cli.addParameter("log");
+      cli.addParameter("-r");
+      cli.addParameter(myRevId + ":" + myRevId);
+      cli.addParameter("--style=" + styleFile.getAbsolutePath());
+
+      ExecResult res = runCommand(cli);
+      return parseFiles(res.getStdout());
+    } finally {
+      FileUtil.delete(styleFile);
+    }
+  }
+
+  private File getStyleFile() throws IOException {
+    File styleFile = FileUtil.createTempFile("hg", "style");
+    FileUtil.writeFile(styleFile,
+            "changeset = \"{file_mods}{file_adds}{file_dels}\"\n" +
+            "file_add = \"A {file_add}\\n\"\n" +
+            "file_del = \"R {file_del}\\n\"\n" +
+            "file_mod = \"M {file_mod}\\n\"");
+    return styleFile;
+  }
+
+  private List<ModifiedFile> parseFiles(final String stdout) {
+    return StatusCommand.parseFiles(stdout);
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CloneCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CloneCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,81 +1,81 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.ExecResult;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-
-public class CloneCommand extends BaseCommand{
-  private String myToId;
-  private boolean myUpdateWorkingDir = true;
-  private String myRepository;
-  private File myWorkingDir;
-  private boolean myUsePullProtocol = true;
-
-  public CloneCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-    myWorkingDir = workingDir;
-    myRepository = getSettings().getRepositoryUrl();
-  }
-
-  /**
-   * Sets repository to clone, by default uses repository from the specified settings
-   * @param repo repository path
-   */
-  public void setRepository(@NotNull String repo) {
-    myRepository = repo;
-  }
-
-  public void setToId(final String toId) {
-    myToId = toId;
-  }
-
-  public void setUpdateWorkingDir(final boolean updateWorkingDir) {
-    myUpdateWorkingDir = updateWorkingDir;
-  }
-
-  public void setUsePullProtocol(boolean usePullProtocol) {
-    myUsePullProtocol = usePullProtocol;
-  }
-
-  public void execute() throws VcsException {
-    GeneralCommandLine cli = createCommandLine();
-    File parent = myWorkingDir.getParentFile();
-    cli.setWorkDirectory(parent.getAbsolutePath());
-    cli.addParameter("clone");
-    if (myToId != null) {
-      cli.addParameter("-r");
-      cli.addParameter(myToId);
-    }
-    if (myUsePullProtocol)
-      cli.addParameter("--pull");
-    if (!myUpdateWorkingDir) {
-      cli.addParameter("-U");
-    }
-    if (getSettings().isUncompressedTransfer()) {
-      cli.addParameter("--uncompressed");
-    }
-    cli.addParameter(myRepository);
-    cli.addParameter(myWorkingDir.getName());
-
-    ExecResult res = runCommand(cli, 24*3600); // some repositories are quite large, we set timeout to 24 hours
-    failIfNonZeroExitCode(cli, res);
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.ExecResult;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+public class CloneCommand extends BaseCommand{
+  private String myToId;
+  private boolean myUpdateWorkingDir = true;
+  private String myRepository;
+  private File myWorkingDir;
+  private boolean myUsePullProtocol = true;
+
+  public CloneCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+    myWorkingDir = workingDir;
+    myRepository = getSettings().getRepositoryUrl();
+  }
+
+  /**
+   * Sets repository to clone, by default uses repository from the specified settings
+   * @param repo repository path
+   */
+  public void setRepository(@NotNull String repo) {
+    myRepository = repo;
+  }
+
+  public void setToId(final String toId) {
+    myToId = toId;
+  }
+
+  public void setUpdateWorkingDir(final boolean updateWorkingDir) {
+    myUpdateWorkingDir = updateWorkingDir;
+  }
+
+  public void setUsePullProtocol(boolean usePullProtocol) {
+    myUsePullProtocol = usePullProtocol;
+  }
+
+  public void execute() throws VcsException {
+    GeneralCommandLine cli = createCommandLine();
+    File parent = myWorkingDir.getParentFile();
+    cli.setWorkDirectory(parent.getAbsolutePath());
+    cli.addParameter("clone");
+    if (myToId != null) {
+      cli.addParameter("-r");
+      cli.addParameter(myToId);
+    }
+    if (myUsePullProtocol)
+      cli.addParameter("--pull");
+    if (!myUpdateWorkingDir) {
+      cli.addParameter("-U");
+    }
+    if (getSettings().isUncompressedTransfer()) {
+      cli.addParameter("--uncompressed");
+    }
+    cli.addParameter(myRepository);
+    cli.addParameter(myWorkingDir.getName());
+
+    ExecResult res = runCommand(cli, 24*3600); // some repositories are quite large, we set timeout to 24 hours
+    failIfNonZeroExitCode(cli, res);
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,119 +1,119 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.ExecResult;
-import jetbrains.buildServer.SimpleCommandLineProcessRunner;
-import jetbrains.buildServer.log.Loggers;
-import jetbrains.buildServer.util.StringUtil;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Collections;
-import java.util.Set;
-
-public class CommandUtil {
-  private static final int DEFAULT_COMMAND_TIMEOUT_SEC = 3600;
-
-  public static void checkCommandFailed(@NotNull String cmdName, @NotNull ExecResult res) throws VcsException {
-    if (res.getExitCode() != 0 || res.getException() != null) {
-      commandFailed(cmdName, res);
-    }
-    if (res.getStderr().length() > 0) {
-      Loggers.VCS.warn("Error output produced by: " + cmdName);
-      Loggers.VCS.warn(res.getStderr());
-    }
-  }
-
-  public static void commandFailed(final String cmdName, final ExecResult res) throws VcsException {
-    String stderr = res.getStderr();
-    String stdout = res.getStdout();
-    String exceptionMessage = getExceptionMessage(res);
-    final String message = "'" + cmdName + "' command failed.\n" +
-            (!StringUtil.isEmpty(stderr) ? "stderr: " + stderr + "\n" : "") +
-            (!StringUtil.isEmpty(stdout) ? "stdout: " + stdout + "\n" : "") +
-            (exceptionMessage != null ? "exception: " + exceptionMessage : "");
-    Loggers.VCS.warn(message);
-    if (hasImportantException(res)) {
-      Loggers.VCS.error("Error during executing '" + cmdName + "'", res.getException());
-    }
-    throw new VcsException(message);
-  }
-
-  @Nullable
-  private static String getExceptionMessage(ExecResult result) {
-    Throwable exception = result.getException();
-    String message = null;
-    if (exception != null) {
-      message = exception.getMessage();
-      if (message == null) {
-        message = exception.getClass().getName();
-      }
-    }
-    return message;
-  }
-
-  private static boolean hasImportantException(ExecResult result) {
-    Throwable exception = result.getException();
-    if (exception != null) {
-      return exception instanceof NullPointerException;
-    } else {
-      return false;
-    }
-  }
-
-  public static ExecResult runCommand(@NotNull GeneralCommandLine cli) throws VcsException {
-    return runCommand(cli, DEFAULT_COMMAND_TIMEOUT_SEC, Collections.<String>emptySet());
-  }
-
-  public static ExecResult runCommand(@NotNull GeneralCommandLine cli, @NotNull Set<String> privateData) throws VcsException {
-    return runCommand(cli, DEFAULT_COMMAND_TIMEOUT_SEC, privateData);
-  }
-
-  public static ExecResult runCommand(@NotNull GeneralCommandLine cli, final int executionTimeout, @NotNull Set<String> privateData) throws VcsException {
-    String cmdStr = removePrivateData(cli.getCommandLineString(), privateData);
-    Loggers.VCS.debug("Run command: " + cmdStr);
-    ExecResult res = SimpleCommandLineProcessRunner.runCommand(cli, null, new SimpleCommandLineProcessRunner.RunCommandEventsAdapter() {
-      @Override
-      public Integer getOutputIdleSecondsTimeout() {
-        return executionTimeout;
-      }
-    });
-
-    removePrivateData(privateData, res);
-
-    CommandUtil.checkCommandFailed(cmdStr, res);
-    Loggers.VCS.debug(res.getStdout());
-    return res;
-  }
-
-  private static void removePrivateData(final Set<String> privateData, final ExecResult res) {
-    res.setStdout(removePrivateData(res.getStdout(), privateData));
-    res.setStderr(removePrivateData(res.getStderr(), privateData));
-  }
-
-  public static String removePrivateData(final String str, final Set<String> privateData) {
-    String result = str;
-    for (String data: privateData) {
-      if (data == null || data.length() == 0) continue;
-      result = result.replace(data, "******");
-    }
-
-    return result;
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.ExecResult;
+import jetbrains.buildServer.SimpleCommandLineProcessRunner;
+import jetbrains.buildServer.log.Loggers;
+import jetbrains.buildServer.util.StringUtil;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.Set;
+
+public class CommandUtil {
+  private static final int DEFAULT_COMMAND_TIMEOUT_SEC = 3600;
+
+  public static void checkCommandFailed(@NotNull String cmdName, @NotNull ExecResult res) throws VcsException {
+    if (res.getExitCode() != 0 || res.getException() != null) {
+      commandFailed(cmdName, res);
+    }
+    if (res.getStderr().length() > 0) {
+      Loggers.VCS.warn("Error output produced by: " + cmdName);
+      Loggers.VCS.warn(res.getStderr());
+    }
+  }
+
+  public static void commandFailed(final String cmdName, final ExecResult res) throws VcsException {
+    String stderr = res.getStderr();
+    String stdout = res.getStdout();
+    String exceptionMessage = getExceptionMessage(res);
+    final String message = "'" + cmdName + "' command failed.\n" +
+            (!StringUtil.isEmpty(stderr) ? "stderr: " + stderr + "\n" : "") +
+            (!StringUtil.isEmpty(stdout) ? "stdout: " + stdout + "\n" : "") +
+            (exceptionMessage != null ? "exception: " + exceptionMessage : "");
+    Loggers.VCS.warn(message);
+    if (hasImportantException(res)) {
+      Loggers.VCS.error("Error during executing '" + cmdName + "'", res.getException());
+    }
+    throw new VcsException(message);
+  }
+
+  @Nullable
+  private static String getExceptionMessage(ExecResult result) {
+    Throwable exception = result.getException();
+    String message = null;
+    if (exception != null) {
+      message = exception.getMessage();
+      if (message == null) {
+        message = exception.getClass().getName();
+      }
+    }
+    return message;
+  }
+
+  private static boolean hasImportantException(ExecResult result) {
+    Throwable exception = result.getException();
+    if (exception != null) {
+      return exception instanceof NullPointerException;
+    } else {
+      return false;
+    }
+  }
+
+  public static ExecResult runCommand(@NotNull GeneralCommandLine cli) throws VcsException {
+    return runCommand(cli, DEFAULT_COMMAND_TIMEOUT_SEC, Collections.<String>emptySet());
+  }
+
+  public static ExecResult runCommand(@NotNull GeneralCommandLine cli, @NotNull Set<String> privateData) throws VcsException {
+    return runCommand(cli, DEFAULT_COMMAND_TIMEOUT_SEC, privateData);
+  }
+
+  public static ExecResult runCommand(@NotNull GeneralCommandLine cli, final int executionTimeout, @NotNull Set<String> privateData) throws VcsException {
+    String cmdStr = removePrivateData(cli.getCommandLineString(), privateData);
+    Loggers.VCS.debug("Run command: " + cmdStr);
+    ExecResult res = SimpleCommandLineProcessRunner.runCommand(cli, null, new SimpleCommandLineProcessRunner.RunCommandEventsAdapter() {
+      @Override
+      public Integer getOutputIdleSecondsTimeout() {
+        return executionTimeout;
+      }
+    });
+
+    removePrivateData(privateData, res);
+
+    CommandUtil.checkCommandFailed(cmdStr, res);
+    Loggers.VCS.debug(res.getStdout());
+    return res;
+  }
+
+  private static void removePrivateData(final Set<String> privateData, final ExecResult res) {
+    res.setStdout(removePrivateData(res.getStdout(), privateData));
+    res.setStderr(removePrivateData(res.getStderr(), privateData));
+  }
+
+  public static String removePrivateData(final String str, final Set<String> privateData) {
+    String result = str;
+    for (String data: privateData) {
+      if (data == null || data.length() == 0) continue;
+      result = result.replace(data, "******");
+    }
+
+    return result;
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/IdentifyCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/IdentifyCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,62 +1,62 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.ExecResult;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-
-/**
- * @author Pavel.Sher
- *         Date: 16.07.2008
- */
-public class IdentifyCommand extends BaseCommand {
-
-  private boolean myInLocalRepository = false;
-  private ChangeSet myChangeSet;
-
-  public IdentifyCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-  }
-
-  public void setInLocalRepository(boolean inLocalRepository) {
-    myInLocalRepository = inLocalRepository;
-  }
-
-  public void setChangeSet(ChangeSet changeSet) {
-    myChangeSet = changeSet;
-  }
-
-  public String execute() throws VcsException {
-    GeneralCommandLine cli = createCL();
-    cli.addParameter("identify");
-    if (myInLocalRepository) {
-      cli.setWorkDirectory(this.getWorkDirectory());
-    } else {
-      cli.addParameter(getSettings().getRepositoryUrl());
-    }
-    if (myChangeSet != null) {
-      cli.addParameter("--rev");
-      cli.addParameter(myChangeSet.getId());
-    }
-    ExecResult res = runCommand(cli);
-    failIfNotEmptyStdErr(cli, res);
-    return res.getStdout();
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.ExecResult;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * @author Pavel.Sher
+ *         Date: 16.07.2008
+ */
+public class IdentifyCommand extends BaseCommand {
+
+  private boolean myInLocalRepository = false;
+  private ChangeSet myChangeSet;
+
+  public IdentifyCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+  }
+
+  public void setInLocalRepository(boolean inLocalRepository) {
+    myInLocalRepository = inLocalRepository;
+  }
+
+  public void setChangeSet(ChangeSet changeSet) {
+    myChangeSet = changeSet;
+  }
+
+  public String execute() throws VcsException {
+    GeneralCommandLine cli = createCL();
+    cli.addParameter("identify");
+    if (myInLocalRepository) {
+      cli.setWorkDirectory(this.getWorkDirectory());
+    } else {
+      cli.addParameter(getSettings().getRepositoryUrl());
+    }
+    if (myChangeSet != null) {
+      cli.addParameter("--rev");
+      cli.addParameter(myChangeSet.getId());
+    }
+    ExecResult res = runCommand(cli);
+    failIfNotEmptyStdErr(cli, res);
+    return res.getStdout();
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,179 +1,179 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import com.intellij.openapi.diagnostic.Logger;
-import jetbrains.buildServer.ExecResult;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
-public class LogCommand extends BaseCommand {
-  private final static Logger LOG = Logger.getInstance(LogCommand.class.getName());
-  private String myFromId;
-  private String myToId;
-  private ArrayList<String> myPaths;
-  private Integer myLimit = null;
-  private static final String CHANGESET_PREFIX = "changeset:";
-  private static final String USER_PREFIX = "user:";
-  private static final String PARENT_PREFIX = "parent:";
-  private static final String DATE_PREFIX = "date:";
-  private static final String DATE_FORMAT = "EEE MMM d HH:mm:ss yyyy Z";
-  private static final String DESCRIPTION_PREFIX = "description:";
-  private static final String FILES_PREFIX = "files:";
-  private String myBranchName;
-
-  public LogCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-    myBranchName = settings.getBranchName();
-  }
-
-  public void setFromRevId(String id) {
-    myFromId = id;
-  }
-
-  public void setToRevId(String id) {
-    myToId = id;
-  }
-
-  public void setPaths(final List<String> relPaths) {
-    myPaths = new ArrayList<String>(relPaths);
-  }
-
-  public void setLimit(final int limit) {
-    myLimit = limit;
-  }
-
-  public void setBranchName(String branchName) {
-    myBranchName = branchName;
-  }
-
-  public List<ChangeSet> execute() throws VcsException {
-    GeneralCommandLine cli = createCommandLine();
-    cli.addParameter("log");
-    cli.addParameter("-v");
-    cli.addParameter("--style");
-    cli.addParameter("default");
-    if (myBranchName != null) {
-      cli.addParameter("-b");
-      cli.addParameter(getSettings().getBranchName());
-    }
-    cli.addParameter("-r");
-    String from = myFromId;
-    if (from == null) from = "0";
-    String to = myToId;
-    if (to == null) to = "tip";
-    cli.addParameter(from + ":" + to);
-    if (myLimit != null) {
-      cli.addParameter("--limit");
-      cli.addParameter(myLimit.toString());
-    }
-    if (myPaths != null) {
-      for (String path: myPaths) {
-        cli.addParameter(path);
-      }
-    }
-
-    ExecResult res = runCommand(cli);
-    return parseChangeSets(res.getStdout());
-  }
-
-  public static List<ChangeSet> parseChangeSets(final String stdout) {
-    List<ChangeSet> result = new ArrayList<ChangeSet>();
-    String[] lines = stdout.split("\n");
-    ChangeSet current = null;
-    int lineNum = 0;
-    boolean insideDescription = false;
-    StringBuilder descr = new StringBuilder();
-    while (lineNum < lines.length) {
-      String line = lines[lineNum];
-      lineNum++;
-
-      if (line.startsWith(CHANGESET_PREFIX)) {
-        insideDescription = false;
-        if (current != null) {
-          current.setDescription(descr.toString().trim());
-          descr.setLength(0);
-        }
-
-        String revAndId = line.substring(CHANGESET_PREFIX.length()).trim();
-        try {
-          current = new ChangeSet(revAndId);
-          result.add(current);
-        } catch (IllegalArgumentException e) {
-          LOG.warn("Unable to extract changeset id from the line: " + line);
-        }
-
-        continue;
-      }
-
-      if (current == null) continue;
-
-      if (line.startsWith(USER_PREFIX)) {
-        current.setUser(line.substring(USER_PREFIX.length()).trim());
-        continue;
-      }
-
-      if (line.startsWith(FILES_PREFIX)) {
-        current.setContainsFiles(true);
-        continue;
-      }
-
-      if (line.startsWith(PARENT_PREFIX)) {
-        String parentRev = line.substring(PARENT_PREFIX.length()).trim();
-        current.addParent(new ChangeSetRevision(parentRev));
-        continue;
-      }
-
-      if (line.startsWith(DATE_PREFIX)) {
-        String date = line.substring(DATE_PREFIX.length()).trim();
-        try {
-          Date parsedDate = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH).parse(date);
-          current.setTimestamp(parsedDate);
-        } catch (ParseException e) {
-          LOG.warn("Unable to parse date: " + date);
-          current = null;
-        }
-
-        continue;
-      }
-
-      if (line.startsWith(DESCRIPTION_PREFIX)) {
-        insideDescription = true;
-        continue;
-      }
-
-      if (insideDescription) {
-        descr.append(line).append("\n");
-      }
-    }
-
-    if (insideDescription) {
-      current.setDescription(descr.toString().trim());
-    }
-
-    return result;
-  }
-
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.openapi.diagnostic.Logger;
+import jetbrains.buildServer.ExecResult;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+public class LogCommand extends BaseCommand {
+  private final static Logger LOG = Logger.getInstance(LogCommand.class.getName());
+  private String myFromId;
+  private String myToId;
+  private ArrayList<String> myPaths;
+  private Integer myLimit = null;
+  private static final String CHANGESET_PREFIX = "changeset:";
+  private static final String USER_PREFIX = "user:";
+  private static final String PARENT_PREFIX = "parent:";
+  private static final String DATE_PREFIX = "date:";
+  private static final String DATE_FORMAT = "EEE MMM d HH:mm:ss yyyy Z";
+  private static final String DESCRIPTION_PREFIX = "description:";
+  private static final String FILES_PREFIX = "files:";
+  private String myBranchName;
+
+  public LogCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+    myBranchName = settings.getBranchName();
+  }
+
+  public void setFromRevId(String id) {
+    myFromId = id;
+  }
+
+  public void setToRevId(String id) {
+    myToId = id;
+  }
+
+  public void setPaths(final List<String> relPaths) {
+    myPaths = new ArrayList<String>(relPaths);
+  }
+
+  public void setLimit(final int limit) {
+    myLimit = limit;
+  }
+
+  public void setBranchName(String branchName) {
+    myBranchName = branchName;
+  }
+
+  public List<ChangeSet> execute() throws VcsException {
+    GeneralCommandLine cli = createCommandLine();
+    cli.addParameter("log");
+    cli.addParameter("-v");
+    cli.addParameter("--style");
+    cli.addParameter("default");
+    if (myBranchName != null) {
+      cli.addParameter("-b");
+      cli.addParameter(getSettings().getBranchName());
+    }
+    cli.addParameter("-r");
+    String from = myFromId;
+    if (from == null) from = "0";
+    String to = myToId;
+    if (to == null) to = "tip";
+    cli.addParameter(from + ":" + to);
+    if (myLimit != null) {
+      cli.addParameter("--limit");
+      cli.addParameter(myLimit.toString());
+    }
+    if (myPaths != null) {
+      for (String path: myPaths) {
+        cli.addParameter(path);
+      }
+    }
+
+    ExecResult res = runCommand(cli);
+    return parseChangeSets(res.getStdout());
+  }
+
+  public static List<ChangeSet> parseChangeSets(final String stdout) {
+    List<ChangeSet> result = new ArrayList<ChangeSet>();
+    String[] lines = stdout.split("\n");
+    ChangeSet current = null;
+    int lineNum = 0;
+    boolean insideDescription = false;
+    StringBuilder descr = new StringBuilder();
+    while (lineNum < lines.length) {
+      String line = lines[lineNum];
+      lineNum++;
+
+      if (line.startsWith(CHANGESET_PREFIX)) {
+        insideDescription = false;
+        if (current != null) {
+          current.setDescription(descr.toString().trim());
+          descr.setLength(0);
+        }
+
+        String revAndId = line.substring(CHANGESET_PREFIX.length()).trim();
+        try {
+          current = new ChangeSet(revAndId);
+          result.add(current);
+        } catch (IllegalArgumentException e) {
+          LOG.warn("Unable to extract changeset id from the line: " + line);
+        }
+
+        continue;
+      }
+
+      if (current == null) continue;
+
+      if (line.startsWith(USER_PREFIX)) {
+        current.setUser(line.substring(USER_PREFIX.length()).trim());
+        continue;
+      }
+
+      if (line.startsWith(FILES_PREFIX)) {
+        current.setContainsFiles(true);
+        continue;
+      }
+
+      if (line.startsWith(PARENT_PREFIX)) {
+        String parentRev = line.substring(PARENT_PREFIX.length()).trim();
+        current.addParent(new ChangeSetRevision(parentRev));
+        continue;
+      }
+
+      if (line.startsWith(DATE_PREFIX)) {
+        String date = line.substring(DATE_PREFIX.length()).trim();
+        try {
+          Date parsedDate = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH).parse(date);
+          current.setTimestamp(parsedDate);
+        } catch (ParseException e) {
+          LOG.warn("Unable to parse date: " + date);
+          current = null;
+        }
+
+        continue;
+      }
+
+      if (line.startsWith(DESCRIPTION_PREFIX)) {
+        insideDescription = true;
+        continue;
+      }
+
+      if (insideDescription) {
+        descr.append(line).append("\n");
+      }
+    }
+
+    if (insideDescription) {
+      current.setDescription(descr.toString().trim());
+    }
+
+    return result;
+  }
+
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ModifiedFile.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ModifiedFile.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,86 +1,86 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Represents repository modified file
- */
-public class ModifiedFile {
-  /**
-   * Type of modification
-   */
-  public static enum Status {
-    ADDED("added"),
-    MODIFIED("modified"),
-    REMOVED("removed"),
-    UNKNOWN("unknown");
-    private String myName;
-
-    Status(@NotNull final String name) {
-      myName = name;
-    }
-
-    @NotNull
-    public String getName() {
-      return myName;
-    }
-  }
-
-  @NotNull private Status myStatus;
-  @NotNull private String myPath;
-
-  public ModifiedFile(@NotNull final Status status, @NotNull final String path) {
-    myStatus = status;
-    myPath = path;
-  }
-
-  /**
-   * Returns type of modification
-   * @return type of modification
-   */
-  @NotNull
-  public Status getStatus() {
-    return myStatus;
-  }
-
-  /**
-   * Returns file path
-   * @return file path
-   */
-  @NotNull
-  public String getPath() {
-    return myPath;
-  }
-
-  @Override
-  public boolean equals(final Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    final ModifiedFile that = (ModifiedFile) o;
-
-    return myPath.equals(that.myPath) && myStatus == that.myStatus;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = myStatus.hashCode();
-    result = 31 * result + myPath.hashCode();
-    return result;
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Represents repository modified file
+ */
+public class ModifiedFile {
+  /**
+   * Type of modification
+   */
+  public static enum Status {
+    ADDED("added"),
+    MODIFIED("modified"),
+    REMOVED("removed"),
+    UNKNOWN("unknown");
+    private String myName;
+
+    Status(@NotNull final String name) {
+      myName = name;
+    }
+
+    @NotNull
+    public String getName() {
+      return myName;
+    }
+  }
+
+  @NotNull private Status myStatus;
+  @NotNull private String myPath;
+
+  public ModifiedFile(@NotNull final Status status, @NotNull final String path) {
+    myStatus = status;
+    myPath = path;
+  }
+
+  /**
+   * Returns type of modification
+   * @return type of modification
+   */
+  @NotNull
+  public Status getStatus() {
+    return myStatus;
+  }
+
+  /**
+   * Returns file path
+   * @return file path
+   */
+  @NotNull
+  public String getPath() {
+    return myPath;
+  }
+
+  @Override
+  public boolean equals(final Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    final ModifiedFile that = (ModifiedFile) o;
+
+    return myPath.equals(that.myPath) && myStatus == that.myStatus;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = myStatus.hashCode();
+    result = 31 * result + myPath.hashCode();
+    return result;
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PullCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PullCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,40 +1,40 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-
-/**
- * @author Pavel.Sher
- *         Date: 14.07.2008
- */
-public class PullCommand extends BaseCommand {
-
-  public PullCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-  }
-
-  public void execute() throws VcsException {
-    GeneralCommandLine cli = createCommandLine();
-    cli.addParameter("pull");
-    cli.addParameter(getSettings().getRepositoryUrl());
-    runCommand(cli);
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * @author Pavel.Sher
+ *         Date: 14.07.2008
+ */
+public class PullCommand extends BaseCommand {
+
+  public PullCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+  }
+
+  public void execute() throws VcsException {
+    GeneralCommandLine cli = createCommandLine();
+    cli.addParameter("pull");
+    cli.addParameter(getSettings().getRepositoryUrl());
+    runCommand(cli);
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PushCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PushCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,49 +1,49 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.ExecResult;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-
-/**
- * @author pavel
- */
-public class PushCommand extends BaseCommand {
-  private boolean myForced;
-
-  public PushCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-  }
-
-  public void setForce(boolean force) {
-    myForced = force;
-  }
-
-  public void execute() throws VcsException {
-    GeneralCommandLine cli = createCommandLine();
-    cli.addParameter("push");
-    if (myForced) {
-      cli.addParameter("-f");
-    }
-    cli.addParameter(getSettings().getRepositoryUrl());
-    ExecResult res = runCommand(cli);
-    failIfNotEmptyStdErr(cli, res);
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.ExecResult;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * @author pavel
+ */
+public class PushCommand extends BaseCommand {
+  private boolean myForced;
+
+  public PushCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+  }
+
+  public void setForce(boolean force) {
+    myForced = force;
+  }
+
+  public void execute() throws VcsException {
+    GeneralCommandLine cli = createCommandLine();
+    cli.addParameter("push");
+    if (myForced) {
+      cli.addParameter("-f");
+    }
+    cli.addParameter(getSettings().getRepositoryUrl());
+    ExecResult res = runCommand(cli);
+    failIfNotEmptyStdErr(cli, res);
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,209 +1,209 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.Constants;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.PathUtil;
-import jetbrains.buildServer.log.Loggers;
-import jetbrains.buildServer.util.StringUtil;
-import jetbrains.buildServer.vcs.VcsRoot;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Represents Mercurial repository settings
- */
-public class Settings {
-  private String myRepository;
-  private String myHgCommandPath;
-  private File myCustomWorkingDir;
-  private String myUsername;
-  private String myPassword;
-  private String myBranchName;
-  private boolean myUncompressedTransfer = false;
-  private static final String DEFAULT_BRANCH_NAME = "default";
-  private String myCustomClonePath;
-
-  public Settings(@NotNull VcsRoot vcsRoot) {
-    myRepository = vcsRoot.getProperty(Constants.REPOSITORY_PROP);
-    myHgCommandPath = vcsRoot.getProperty(Constants.HG_COMMAND_PATH_PROP);
-    myBranchName = vcsRoot.getProperty(Constants.BRANCH_NAME_PROP);
-    myCustomClonePath = vcsRoot.getProperty(Constants.SERVER_CLONE_PATH_PROP);
-    myUsername = vcsRoot.getProperty(Constants.USERNAME);
-    myPassword = vcsRoot.getProperty(Constants.PASSWORD);
-    myUncompressedTransfer = "true".equals(vcsRoot.getProperty(Constants.UNCOMPRESSED_TRANSFER));
-  }
-
-  public String getCustomClonePath() {
-    return myCustomClonePath;
-  }
-
-  public String getRepository() {
-    return myRepository;
-  }
-
-  /**
-   * Returns name of the branch to use (returns 'default' if no branch specified)
-   * @return see above
-   */
-  @NotNull
-  public String getBranchName() {
-    return StringUtil.isEmpty(myBranchName) ? DEFAULT_BRANCH_NAME : myBranchName;
-  }
-
-  /**
-   * Returns true if current branch is default branch
-   * @return see above
-   */
-  public boolean isDefaultBranch() {
-    return getBranchName().equals(DEFAULT_BRANCH_NAME);
-  }
-
-  public boolean isUncompressedTransfer() {
-    return myUncompressedTransfer;
-  }
-
-  /**
-   * Returns path to hg command
-   * @return path to hg command
-   */
-  @NotNull
-  public String getHgCommandPath() {
-    return myHgCommandPath;
-  }
-
-  public String getUsername() {
-    return myUsername;
-  }
-
-  public String getPassword() {
-    return myPassword;
-  }
-
-  private final static Set<String> AUTH_PROTOS = new HashSet<String>();
-  static {
-    AUTH_PROTOS.add("http");
-    AUTH_PROTOS.add("https");
-    AUTH_PROTOS.add("ssh");
-  }
-
-  /**
-   * Returns URL to use for push command
-   * @return URL to use for push command
-   */
-  public String getRepositoryUrl() {
-    if (isRequireCredentials()) {
-      if (containsCredentials(myRepository)) return myRepository;
-      try {
-        return createURLWithCredentials(myRepository);
-      } catch (MalformedURLException e) {
-        Loggers.VCS.warn("Error while parsing url " + myRepository, e);
-      }
-      return myRepository;
-    } else {
-      return myRepository;
-    }
-  }
-
-  private boolean containsCredentials(final String repository) {
-    try {
-      URL url = new URL(repository);
-      String userInfo = url.getUserInfo();
-      return userInfo != null && userInfo.contains(":");
-    } catch (MalformedURLException e) {
-      return false;
-    }
-  }
-
-  private String createURLWithCredentials(final String originalUrl) throws MalformedURLException {
-    String userInfo = createUserInfo();
-    if (!"".equals(userInfo)) {
-      URL url = new URL(originalUrl);
-      return url.getProtocol() + "://"
-              + userInfo + "@"
-              + url.getHost()
-              + (url.getPort() != -1 ? ":" + url.getPort() : "")
-              + url.getFile()
-              + (url.getRef() != null ? url.getRef() : "");
-    } else {
-      return originalUrl;
-    }
-  }
-
-  private boolean isRequireCredentials() {
-    for (String scheme : AUTH_PROTOS) {
-      if (myRepository.startsWith(scheme + ":")) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private String createUserInfo() {
-    String userInfo = "";
-    if (!StringUtil.isEmpty(myUsername)) {
-      userInfo += myUsername;
-      if (!StringUtil.isEmpty(myPassword)) {
-        userInfo += ":" + myPassword;
-      }
-    }
-    return getEscapedUserInfo(userInfo);
-  }
-
-  private static String getEscapedUserInfo(String userInfo) {
-    try {
-      URI uri = new URI("http", userInfo, "somewhere.com", 80, "", "", "");
-      String escapedURI = uri.toASCIIString();
-      int from = "http://".length();
-      int to = escapedURI.indexOf("somewhere.com") - 1;
-      return escapedURI.substring(from, to);
-    } catch (URISyntaxException e) {
-      assert false;
-    }
-    return userInfo;
-  }
-
-  /**
-   * Set custom working dir for vcs root. This option make sence only for server-side checkout
-   * @param customWorkingDir custom working dir
-   */
-  public void setCustomWorkingDir(@NotNull final File customWorkingDir) {
-    myCustomWorkingDir = PathUtil.getCanonicalFile(customWorkingDir);
-  }
-
-  /**
-   * Returns custom working dir for root or null if default working dir should be used.
-   * This options make sence only with server-side checkout.
-   * @return see above
-   */
-  @Nullable
-  public File getCustomWorkingDir() {
-    return myCustomWorkingDir;
-  }
-
-  public static boolean isValidRepository(File dir) {
-    // need better way to check that repository copy is ok
-    return dir.isDirectory() && new File(dir, ".hg").isDirectory();
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.Constants;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.PathUtil;
+import jetbrains.buildServer.log.Loggers;
+import jetbrains.buildServer.util.StringUtil;
+import jetbrains.buildServer.vcs.VcsRoot;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Represents Mercurial repository settings
+ */
+public class Settings {
+  private String myRepository;
+  private String myHgCommandPath;
+  private File myCustomWorkingDir;
+  private String myUsername;
+  private String myPassword;
+  private String myBranchName;
+  private boolean myUncompressedTransfer = false;
+  private static final String DEFAULT_BRANCH_NAME = "default";
+  private String myCustomClonePath;
+
+  public Settings(@NotNull VcsRoot vcsRoot) {
+    myRepository = vcsRoot.getProperty(Constants.REPOSITORY_PROP);
+    myHgCommandPath = vcsRoot.getProperty(Constants.HG_COMMAND_PATH_PROP);
+    myBranchName = vcsRoot.getProperty(Constants.BRANCH_NAME_PROP);
+    myCustomClonePath = vcsRoot.getProperty(Constants.SERVER_CLONE_PATH_PROP);
+    myUsername = vcsRoot.getProperty(Constants.USERNAME);
+    myPassword = vcsRoot.getProperty(Constants.PASSWORD);
+    myUncompressedTransfer = "true".equals(vcsRoot.getProperty(Constants.UNCOMPRESSED_TRANSFER));
+  }
+
+  public String getCustomClonePath() {
+    return myCustomClonePath;
+  }
+
+  public String getRepository() {
+    return myRepository;
+  }
+
+  /**
+   * Returns name of the branch to use (returns 'default' if no branch specified)
+   * @return see above
+   */
+  @NotNull
+  public String getBranchName() {
+    return StringUtil.isEmpty(myBranchName) ? DEFAULT_BRANCH_NAME : myBranchName;
+  }
+
+  /**
+   * Returns true if current branch is default branch
+   * @return see above
+   */
+  public boolean isDefaultBranch() {
+    return getBranchName().equals(DEFAULT_BRANCH_NAME);
+  }
+
+  public boolean isUncompressedTransfer() {
+    return myUncompressedTransfer;
+  }
+
+  /**
+   * Returns path to hg command
+   * @return path to hg command
+   */
+  @NotNull
+  public String getHgCommandPath() {
+    return myHgCommandPath;
+  }
+
+  public String getUsername() {
+    return myUsername;
+  }
+
+  public String getPassword() {
+    return myPassword;
+  }
+
+  private final static Set<String> AUTH_PROTOS = new HashSet<String>();
+  static {
+    AUTH_PROTOS.add("http");
+    AUTH_PROTOS.add("https");
+    AUTH_PROTOS.add("ssh");
+  }
+
+  /**
+   * Returns URL to use for push command
+   * @return URL to use for push command
+   */
+  public String getRepositoryUrl() {
+    if (isRequireCredentials()) {
+      if (containsCredentials(myRepository)) return myRepository;
+      try {
+        return createURLWithCredentials(myRepository);
+      } catch (MalformedURLException e) {
+        Loggers.VCS.warn("Error while parsing url " + myRepository, e);
+      }
+      return myRepository;
+    } else {
+      return myRepository;
+    }
+  }
+
+  private boolean containsCredentials(final String repository) {
+    try {
+      URL url = new URL(repository);
+      String userInfo = url.getUserInfo();
+      return userInfo != null && userInfo.contains(":");
+    } catch (MalformedURLException e) {
+      return false;
+    }
+  }
+
+  private String createURLWithCredentials(final String originalUrl) throws MalformedURLException {
+    String userInfo = createUserInfo();
+    if (!"".equals(userInfo)) {
+      URL url = new URL(originalUrl);
+      return url.getProtocol() + "://"
+              + userInfo + "@"
+              + url.getHost()
+              + (url.getPort() != -1 ? ":" + url.getPort() : "")
+              + url.getFile()
+              + (url.getRef() != null ? url.getRef() : "");
+    } else {
+      return originalUrl;
+    }
+  }
+
+  private boolean isRequireCredentials() {
+    for (String scheme : AUTH_PROTOS) {
+      if (myRepository.startsWith(scheme + ":")) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private String createUserInfo() {
+    String userInfo = "";
+    if (!StringUtil.isEmpty(myUsername)) {
+      userInfo += myUsername;
+      if (!StringUtil.isEmpty(myPassword)) {
+        userInfo += ":" + myPassword;
+      }
+    }
+    return getEscapedUserInfo(userInfo);
+  }
+
+  private static String getEscapedUserInfo(String userInfo) {
+    try {
+      URI uri = new URI("http", userInfo, "somewhere.com", 80, "", "", "");
+      String escapedURI = uri.toASCIIString();
+      int from = "http://".length();
+      int to = escapedURI.indexOf("somewhere.com") - 1;
+      return escapedURI.substring(from, to);
+    } catch (URISyntaxException e) {
+      assert false;
+    }
+    return userInfo;
+  }
+
+  /**
+   * Set custom working dir for vcs root. This option make sence only for server-side checkout
+   * @param customWorkingDir custom working dir
+   */
+  public void setCustomWorkingDir(@NotNull final File customWorkingDir) {
+    myCustomWorkingDir = PathUtil.getCanonicalFile(customWorkingDir);
+  }
+
+  /**
+   * Returns custom working dir for root or null if default working dir should be used.
+   * This options make sence only with server-side checkout.
+   * @return see above
+   */
+  @Nullable
+  public File getCustomWorkingDir() {
+    return myCustomWorkingDir;
+  }
+
+  public static boolean isValidRepository(File dir) {
+    // need better way to check that repository copy is ok
+    return dir.isDirectory() && new File(dir, ".hg").isDirectory();
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/StatusCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/StatusCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,78 +1,78 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.ExecResult;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-public class StatusCommand extends BaseCommand {
-  private String myFromId;
-  private String myToId;
-
-  public StatusCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-  }
-
-  public void setFromRevId(final String fromId) {
-    myFromId = fromId;
-  }
-
-  public void setToRevId(final String toId) {
-    myToId = toId;
-  }
-
-  public List<ModifiedFile> execute() throws VcsException {
-    GeneralCommandLine cli = createCommandLine();
-    cli.addParameter("status");
-    cli.addParameter("--rev");
-    String from = myFromId;
-    if (from == null) from = "0";
-    String to = myToId;
-    if (to == null) to = "0";
-    cli.addParameter(from + ":" + to);
-    ExecResult res = runCommand(cli);
-    return parseFiles(res.getStdout());
-  }
-
-  public static List<ModifiedFile> parseFiles(final String stdout) {
-    List<ModifiedFile> result = new ArrayList<ModifiedFile>();
-    String[] lines = stdout.split("\n");
-    for (String line: lines) {
-      if (line.length() == 0) continue;
-      char modifier = line.charAt(0);
-      String path = line.substring(2);
-      ModifiedFile.Status status = toStatus(modifier);
-      if (status == ModifiedFile.Status.UNKNOWN) continue;
-      result.add(new ModifiedFile(status, path));
-    }
-    return result;
-  }
-
-  public static ModifiedFile.Status toStatus(final char modifier) {
-    switch (modifier) {
-      case 'A': return ModifiedFile.Status.ADDED;
-      case 'M': return ModifiedFile.Status.MODIFIED;
-      case 'R': return ModifiedFile.Status.REMOVED;
-      default: return ModifiedFile.Status.UNKNOWN;
-    }
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.ExecResult;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class StatusCommand extends BaseCommand {
+  private String myFromId;
+  private String myToId;
+
+  public StatusCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+  }
+
+  public void setFromRevId(final String fromId) {
+    myFromId = fromId;
+  }
+
+  public void setToRevId(final String toId) {
+    myToId = toId;
+  }
+
+  public List<ModifiedFile> execute() throws VcsException {
+    GeneralCommandLine cli = createCommandLine();
+    cli.addParameter("status");
+    cli.addParameter("--rev");
+    String from = myFromId;
+    if (from == null) from = "0";
+    String to = myToId;
+    if (to == null) to = "0";
+    cli.addParameter(from + ":" + to);
+    ExecResult res = runCommand(cli);
+    return parseFiles(res.getStdout());
+  }
+
+  public static List<ModifiedFile> parseFiles(final String stdout) {
+    List<ModifiedFile> result = new ArrayList<ModifiedFile>();
+    String[] lines = stdout.split("\n");
+    for (String line: lines) {
+      if (line.length() == 0) continue;
+      char modifier = line.charAt(0);
+      String path = line.substring(2);
+      ModifiedFile.Status status = toStatus(modifier);
+      if (status == ModifiedFile.Status.UNKNOWN) continue;
+      result.add(new ModifiedFile(status, path));
+    }
+    return result;
+  }
+
+  public static ModifiedFile.Status toStatus(final char modifier) {
+    switch (modifier) {
+      case 'A': return ModifiedFile.Status.ADDED;
+      case 'M': return ModifiedFile.Status.MODIFIED;
+      case 'R': return ModifiedFile.Status.REMOVED;
+      default: return ModifiedFile.Status.UNKNOWN;
+    }
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/TagCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/TagCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,48 +1,48 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-
-public class TagCommand extends BaseCommand {
-  private String myTag;
-  private String myRevId;
-
-  public TagCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-  }
-
-  public void setTag(@NotNull final String tag) {
-    myTag = tag;
-  }
-
-  public void setRevId(@NotNull final String revId) {
-    myRevId = revId;
-  }
-
-  public void execute() throws VcsException {
-    GeneralCommandLine cli = createCommandLine();
-    cli.addParameter("tag");
-    cli.addParameter("-r");
-    cli.addParameter(myRevId);
-    cli.addParameter(myTag);
-    runCommand(cli);
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+public class TagCommand extends BaseCommand {
+  private String myTag;
+  private String myRevId;
+
+  public TagCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+  }
+
+  public void setTag(@NotNull final String tag) {
+    myTag = tag;
+  }
+
+  public void setRevId(@NotNull final String revId) {
+    myRevId = revId;
+  }
+
+  public void execute() throws VcsException {
+    GeneralCommandLine cli = createCommandLine();
+    cli.addParameter("tag");
+    cli.addParameter("-r");
+    cli.addParameter(myRevId);
+    cli.addParameter(myTag);
+    runCommand(cli);
+  }
+}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/UpdateCommand.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/UpdateCommand.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,50 +1,50 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-
-public class UpdateCommand extends BaseCommand {
-
-  private static final int UPDATE_TIMEOUT_SECONDS = 8 * 3600;//8 hours
-
-  private String myToId;
-
-  public UpdateCommand(@NotNull Settings settings, @NotNull File workingDir) {
-    super(settings, workingDir);
-  }
-
-  public void setToId(final String toId) {
-    myToId = toId;
-  }
-
-  public void execute() throws VcsException {
-    GeneralCommandLine cli = createCommandLine();
-    cli.addParameter("update");
-    cli.addParameter("-C");
-    cli.addParameter("-r");
-    if (myToId != null) {
-      cli.addParameter(myToId);
-    } else {
-      cli.addParameter(getSettings().getBranchName());
-    }
-    runCommand(cli, UPDATE_TIMEOUT_SECONDS);
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+public class UpdateCommand extends BaseCommand {
+
+  private static final int UPDATE_TIMEOUT_SECONDS = 8 * 3600;//8 hours
+
+  private String myToId;
+
+  public UpdateCommand(@NotNull Settings settings, @NotNull File workingDir) {
+    super(settings, workingDir);
+  }
+
+  public void setToId(final String toId) {
+    myToId = toId;
+  }
+
+  public void execute() throws VcsException {
+    GeneralCommandLine cli = createCommandLine();
+    cli.addParameter("update");
+    cli.addParameter("-C");
+    cli.addParameter("-r");
+    if (myToId != null) {
+      cli.addParameter(myToId);
+    } else {
+      cli.addParameter(getSettings().getBranchName());
+    }
+    runCommand(cli, UPDATE_TIMEOUT_SECONDS);
+  }
+}
--- a/mercurial-server/src/META-INF/build-server-plugin-mercurial.xml	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-server/src/META-INF/build-server-plugin-mercurial.xml	Wed Jul 20 12:04:08 2011 +0400
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
-
-<beans default-autowire="constructor">
-  <bean id="mercurialServer" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialVcsSupport" />
-  <bean id="config" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.PluginConfigImpl" />
-</beans>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
+
+<beans default-autowire="constructor">
+  <bean id="mercurialServer" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialVcsSupport" />
+  <bean id="config" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.PluginConfigImpl" />
+</beans>
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutTest.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutTest.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,225 +1,225 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
-
-import jetbrains.buildServer.agent.AgentRunningBuild;
-import jetbrains.buildServer.agent.BuildAgentConfiguration;
-import jetbrains.buildServer.agent.BuildProgressLogger;
-import jetbrains.buildServer.util.FileUtil;
-import jetbrains.buildServer.vcs.CheckoutRules;
-import jetbrains.buildServer.vcs.IncludeRule;
-import jetbrains.buildServer.vcs.VcsException;
-import jetbrains.buildServer.vcs.VcsRoot;
-import org.jmock.Expectations;
-import org.jmock.Mockery;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Pavel.Sher
- *         Date: 30.07.2008
- */
-@Test
-public class AgentSideCheckoutTest extends BaseMercurialTestCase {
-  private MercurialAgentSideVcsSupport myVcsSupport;
-  private File myWorkDir;
-  private File myMirrorsRootDir;
-  private Mockery myContext;
-  private BuildProgressLogger myLogger;
-  private int myBuildCounter = 0;
-
-  @Override
-  @BeforeMethod
-  protected void setUp() throws Exception {
-    super.setUp();
-
-    myContext = new Mockery();
-
-    myMirrorsRootDir = myTempFiles.createTempDir();
-
-    final BuildAgentConfiguration agentConfig = myContext.mock(BuildAgentConfiguration.class);
-    myContext.checking(new Expectations() {{
-      allowing(agentConfig).getCacheDirectory("mercurial"); will(returnValue(myMirrorsRootDir));
-    }});
-
-    myVcsSupport = new MercurialAgentSideVcsSupport(agentConfig);
-
-    myLogger = myContext.mock(BuildProgressLogger.class);
-    myContext.checking(new Expectations() {{
-      allowing(myLogger).message(with(any(String.class)));
-    }});
-
-    myWorkDir = myTempFiles.createTempDir();
-
-  }
-
-  public void checkout_on_agent() throws IOException, VcsException {
-    testUpdate(createVcsRoot(simpleRepo()), "4:b06a290a363b", "cleanPatch1/after", new IncludeRule(".", ".", null));
-  }
-
-  public void checkout_on_agent_include_rule_with_mapping() throws IOException, VcsException {
-    testUpdate(createVcsRoot(simpleRepo()), "4:b06a290a363b", "cleanPatch1/after", new IncludeRule("+:.", "subdir", null));
-  }
-
-  private void testUpdate(final VcsRoot vcsRoot, String version, String expected, final IncludeRule includeRule) throws VcsException, IOException {
-    File workDir = doUpdate(vcsRoot, version, includeRule);
-
-    checkWorkingDir(expected, workDir);
-  }
-
-  private void checkWorkingDir(final String expected, final File workDir) throws IOException {
-    FileUtil.delete(new File(workDir, ".hg"));
-    checkDirectoriesAreEqual(new File(getTestDataPath(), expected), workDir);
-  }
-
-  private File doUpdate(final VcsRoot vcsRoot, final String version, final IncludeRule includeRule) throws VcsException {
-    return doUpdate(vcsRoot, version, includeRule, false);
-  }
-
-  private File doUpdate(final VcsRoot vcsRoot, final String version, final IncludeRule includeRule, boolean useLocalMirrors) throws VcsException {
-    File actualWorkDir = new File(myWorkDir, includeRule.getTo());
-    final Map<String, String> sharedConfigParameters = new HashMap<String, String>();
-    sharedConfigParameters.put("teamcity.hg.use.local.mirrors", String.valueOf(useLocalMirrors));
-    final AgentRunningBuild build = myContext.mock(AgentRunningBuild.class, "build" + myBuildCounter++);
-    myContext.checking(new Expectations() {{
-      allowing(build).getBuildLogger(); will(returnValue(myLogger));
-      allowing(build).getSharedConfigParameters(); will(returnValue(sharedConfigParameters));
-    }});
-    myVcsSupport.getUpdater(vcsRoot, new CheckoutRules(""), version, myWorkDir, build, false).process(includeRule, actualWorkDir);
-
-    File hgDir = new File(actualWorkDir, ".hg");
-    assertTrue(hgDir.isDirectory());
-    return actualWorkDir;
-  }
-
-  public void checkout_on_agent_from_branch() throws IOException, VcsException {
-    testUpdate(createVcsRoot(simpleRepo(), "test_branch"), "7:376dcf05cd2a", "patch3/after", new IncludeRule(".", ".", null));
-  }
-
-  public void update_on_agent() throws IOException, VcsException {
-    VcsRoot vcsRoot = createVcsRoot(simpleRepo());
-    doUpdate(vcsRoot, "3:9522278aa38d", new IncludeRule(".", ".", null));
-    File workDir = doUpdate(vcsRoot, "4:b06a290a363b", new IncludeRule(".", ".", null));
-
-    checkWorkingDir("patch1/after", workDir);
-  }
-
-  public void update_on_agent_with_include_rule() throws IOException, VcsException {
-    VcsRoot vcsRoot = createVcsRoot(simpleRepo());
-    doUpdate(vcsRoot, "3:9522278aa38d", new IncludeRule(".", "subdir", null));
-    File workDir = doUpdate(vcsRoot, "4:b06a290a363b", new IncludeRule(".", "subdir", null));
-
-    checkWorkingDir("patch1/after", workDir);
-  }
-
-  public void update_on_agent_from_branch() throws IOException, VcsException {
-    VcsRoot vcsRoot = createVcsRoot(simpleRepo(), "test_branch");
-    doUpdate(vcsRoot, "7:376dcf05cd2a", new IncludeRule(".", ".", null));
-    File workDir = doUpdate(vcsRoot, "8:04c3ae4c6312", new IncludeRule(".", ".", null));
-
-    checkWorkingDir("patch4/after", workDir);
-  }
-
-  public void by_default_local_mirror_not_created() throws IOException, VcsException {
-    List<File> mirrors = FileUtil.getSubDirectories(myMirrorsRootDir);
-    assertTrue(mirrors.isEmpty());
-    VcsRoot root = createVcsRoot(simpleRepo());
-    doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null));
-    mirrors = FileUtil.getSubDirectories(myMirrorsRootDir);
-    //though some dirs are created - they are empty => there were no clones into local mirrors
-    for (File mirror : mirrors) {
-      assertTrue(FileUtil.getSubDirectories(mirror).isEmpty());
-    }
-  }
-
-  public void local_mirror_is_created() throws IOException, VcsException {
-    List<File> mirrors = FileUtil.getSubDirectories(myMirrorsRootDir);
-    assertTrue(mirrors.isEmpty());
-    VcsRoot root = createVcsRoot(simpleRepo());
-    doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null), true);
-    mirrors = FileUtil.getSubDirectories(myMirrorsRootDir);
-    assertEquals(1, mirrors.size());
-    File mirror = mirrors.get(0);
-    File dotHg = new File(mirror, ".hg");
-    assertTrue(dotHg.exists());
-    File hgrc = new File(dotHg, "hgrc");
-    String hgrcContent = FileUtil.readText(hgrc);
-    assertTrue(hgrcContent.contains("default = " + root.getProperty(Constants.REPOSITORY_PROP)));
-  }
-
-  public void new_repository_is_cloned_from_local_mirror() throws IOException, VcsException {
-    VcsRoot root = createVcsRoot(simpleRepo());
-    File workingDir = doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null), true);
-    File mirrorDir = FileUtil.getSubDirectories(myMirrorsRootDir).get(0);
-    File hgrc = new File(workingDir, ".hg" + File.separator + "hgrc");
-    String hgrcContent = FileUtil.readText(hgrc);
-    assertTrue(hgrcContent.contains("default = " + mirrorDir.getCanonicalPath()));
-  }
-
-  public void repository_cloned_from_remote_start_cloning_from_local_mirror() throws IOException, VcsException {
-    VcsRoot root = createVcsRoot(simpleRepo());
-    //clone from remote repository
-    File workingDir = doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null));
-    String hgrcContent = FileUtil.readText(new File(workingDir, ".hg" + File.separator + "hgrc"));
-
-    File workingDir2 = doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null), true);
-    File newMirrorDir = FileUtil.getSubDirectories(myMirrorsRootDir).get(0);
-    String hgrcContent2 = FileUtil.readText(new File(workingDir2, ".hg" + File.separator + "hgrc"));
-    assertFalse(hgrcContent2.equals(hgrcContent));//repository settings are changed
-    assertTrue(hgrcContent2.contains("default = " + newMirrorDir.getCanonicalPath()));//now it clones from local mirror
-  }
-
-  public void repository_cloned_from_local_mirror_start_cloning_from_remote() throws IOException, VcsException {
-    VcsRoot root = createVcsRoot(simpleRepo());
-    //clone from remote repository
-    File workingDir = doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null), true);
-    String hgrcContent = FileUtil.readText(new File(workingDir, ".hg" + File.separator + "hgrc"));
-    File newMirrorDir = FileUtil.getSubDirectories(myMirrorsRootDir).get(0);
-    assertTrue(hgrcContent.contains("default = " + newMirrorDir.getCanonicalPath()));//now it clones from local mirror
-
-    File workingDir2 = doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null));
-    String hgrcContent2 = FileUtil.readText(new File(workingDir2, ".hg" + File.separator + "hgrc"));
-    assertFalse(hgrcContent2.equals(hgrcContent));//repository settings are changed
-    assertTrue(hgrcContent2.contains("default = " + root.getProperty(Constants.REPOSITORY_PROP)));//now it clones from remote
-  }
-
-  /**
-   * TW-15984
-   */
-  public void should_be_able_to_clone_into_non_empty_dir() throws IOException, VcsException {
-    VcsRoot vcsRoot = createVcsRoot(simpleRepo());
-    doUpdate(vcsRoot, "3:9522278aa38d", new IncludeRule(".", "subdir", null));
-    doUpdate(vcsRoot, "4:b06a290a363b", new IncludeRule(".", ".", null));
-  }
-
-  public void cloned_repo_should_contains_default_parameter_in_hgrc() throws VcsException, IOException {
-    VcsRoot root = createVcsRoot(simpleRepo());
-    File workingDir = doUpdate(root, "4:b06a290a363b", new IncludeRule(".", ".", null));
-    File hgrc = new File(workingDir, ".hg" + File.separator + "hgrc");
-    String hgrcContent = FileUtil.readText(hgrc);
-    assertTrue(hgrcContent.contains("default = " + root.getProperty(Constants.REPOSITORY_PROP)));
-  }
-
-  protected String getTestDataPath() {
-    return "mercurial-tests/testData";
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import jetbrains.buildServer.agent.AgentRunningBuild;
+import jetbrains.buildServer.agent.BuildAgentConfiguration;
+import jetbrains.buildServer.agent.BuildProgressLogger;
+import jetbrains.buildServer.util.FileUtil;
+import jetbrains.buildServer.vcs.CheckoutRules;
+import jetbrains.buildServer.vcs.IncludeRule;
+import jetbrains.buildServer.vcs.VcsException;
+import jetbrains.buildServer.vcs.VcsRoot;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Pavel.Sher
+ *         Date: 30.07.2008
+ */
+@Test
+public class AgentSideCheckoutTest extends BaseMercurialTestCase {
+  private MercurialAgentSideVcsSupport myVcsSupport;
+  private File myWorkDir;
+  private File myMirrorsRootDir;
+  private Mockery myContext;
+  private BuildProgressLogger myLogger;
+  private int myBuildCounter = 0;
+
+  @Override
+  @BeforeMethod
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    myContext = new Mockery();
+
+    myMirrorsRootDir = myTempFiles.createTempDir();
+
+    final BuildAgentConfiguration agentConfig = myContext.mock(BuildAgentConfiguration.class);
+    myContext.checking(new Expectations() {{
+      allowing(agentConfig).getCacheDirectory("mercurial"); will(returnValue(myMirrorsRootDir));
+    }});
+
+    myVcsSupport = new MercurialAgentSideVcsSupport(agentConfig);
+
+    myLogger = myContext.mock(BuildProgressLogger.class);
+    myContext.checking(new Expectations() {{
+      allowing(myLogger).message(with(any(String.class)));
+    }});
+
+    myWorkDir = myTempFiles.createTempDir();
+
+  }
+
+  public void checkout_on_agent() throws IOException, VcsException {
+    testUpdate(createVcsRoot(simpleRepo()), "4:b06a290a363b", "cleanPatch1/after", new IncludeRule(".", ".", null));
+  }
+
+  public void checkout_on_agent_include_rule_with_mapping() throws IOException, VcsException {
+    testUpdate(createVcsRoot(simpleRepo()), "4:b06a290a363b", "cleanPatch1/after", new IncludeRule("+:.", "subdir", null));
+  }
+
+  private void testUpdate(final VcsRoot vcsRoot, String version, String expected, final IncludeRule includeRule) throws VcsException, IOException {
+    File workDir = doUpdate(vcsRoot, version, includeRule);
+
+    checkWorkingDir(expected, workDir);
+  }
+
+  private void checkWorkingDir(final String expected, final File workDir) throws IOException {
+    FileUtil.delete(new File(workDir, ".hg"));
+    checkDirectoriesAreEqual(new File(getTestDataPath(), expected), workDir);
+  }
+
+  private File doUpdate(final VcsRoot vcsRoot, final String version, final IncludeRule includeRule) throws VcsException {
+    return doUpdate(vcsRoot, version, includeRule, false);
+  }
+
+  private File doUpdate(final VcsRoot vcsRoot, final String version, final IncludeRule includeRule, boolean useLocalMirrors) throws VcsException {
+    File actualWorkDir = new File(myWorkDir, includeRule.getTo());
+    final Map<String, String> sharedConfigParameters = new HashMap<String, String>();
+    sharedConfigParameters.put("teamcity.hg.use.local.mirrors", String.valueOf(useLocalMirrors));
+    final AgentRunningBuild build = myContext.mock(AgentRunningBuild.class, "build" + myBuildCounter++);
+    myContext.checking(new Expectations() {{
+      allowing(build).getBuildLogger(); will(returnValue(myLogger));
+      allowing(build).getSharedConfigParameters(); will(returnValue(sharedConfigParameters));
+    }});
+    myVcsSupport.getUpdater(vcsRoot, new CheckoutRules(""), version, myWorkDir, build, false).process(includeRule, actualWorkDir);
+
+    File hgDir = new File(actualWorkDir, ".hg");
+    assertTrue(hgDir.isDirectory());
+    return actualWorkDir;
+  }
+
+  public void checkout_on_agent_from_branch() throws IOException, VcsException {
+    testUpdate(createVcsRoot(simpleRepo(), "test_branch"), "7:376dcf05cd2a", "patch3/after", new IncludeRule(".", ".", null));
+  }
+
+  public void update_on_agent() throws IOException, VcsException {
+    VcsRoot vcsRoot = createVcsRoot(simpleRepo());
+    doUpdate(vcsRoot, "3:9522278aa38d", new IncludeRule(".", ".", null));
+    File workDir = doUpdate(vcsRoot, "4:b06a290a363b", new IncludeRule(".", ".", null));
+
+    checkWorkingDir("patch1/after", workDir);
+  }
+
+  public void update_on_agent_with_include_rule() throws IOException, VcsException {
+    VcsRoot vcsRoot = createVcsRoot(simpleRepo());
+    doUpdate(vcsRoot, "3:9522278aa38d", new IncludeRule(".", "subdir", null));
+    File workDir = doUpdate(vcsRoot, "4:b06a290a363b", new IncludeRule(".", "subdir", null));
+
+    checkWorkingDir("patch1/after", workDir);
+  }
+
+  public void update_on_agent_from_branch() throws IOException, VcsException {
+    VcsRoot vcsRoot = createVcsRoot(simpleRepo(), "test_branch");
+    doUpdate(vcsRoot, "7:376dcf05cd2a", new IncludeRule(".", ".", null));
+    File workDir = doUpdate(vcsRoot, "8:04c3ae4c6312", new IncludeRule(".", ".", null));
+
+    checkWorkingDir("patch4/after", workDir);
+  }
+
+  public void by_default_local_mirror_not_created() throws IOException, VcsException {
+    List<File> mirrors = FileUtil.getSubDirectories(myMirrorsRootDir);
+    assertTrue(mirrors.isEmpty());
+    VcsRoot root = createVcsRoot(simpleRepo());
+    doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null));
+    mirrors = FileUtil.getSubDirectories(myMirrorsRootDir);
+    //though some dirs are created - they are empty => there were no clones into local mirrors
+    for (File mirror : mirrors) {
+      assertTrue(FileUtil.getSubDirectories(mirror).isEmpty());
+    }
+  }
+
+  public void local_mirror_is_created() throws IOException, VcsException {
+    List<File> mirrors = FileUtil.getSubDirectories(myMirrorsRootDir);
+    assertTrue(mirrors.isEmpty());
+    VcsRoot root = createVcsRoot(simpleRepo());
+    doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null), true);
+    mirrors = FileUtil.getSubDirectories(myMirrorsRootDir);
+    assertEquals(1, mirrors.size());
+    File mirror = mirrors.get(0);
+    File dotHg = new File(mirror, ".hg");
+    assertTrue(dotHg.exists());
+    File hgrc = new File(dotHg, "hgrc");
+    String hgrcContent = FileUtil.readText(hgrc);
+    assertTrue(hgrcContent.contains("default = " + root.getProperty(Constants.REPOSITORY_PROP)));
+  }
+
+  public void new_repository_is_cloned_from_local_mirror() throws IOException, VcsException {
+    VcsRoot root = createVcsRoot(simpleRepo());
+    File workingDir = doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null), true);
+    File mirrorDir = FileUtil.getSubDirectories(myMirrorsRootDir).get(0);
+    File hgrc = new File(workingDir, ".hg" + File.separator + "hgrc");
+    String hgrcContent = FileUtil.readText(hgrc);
+    assertTrue(hgrcContent.contains("default = " + mirrorDir.getCanonicalPath()));
+  }
+
+  public void repository_cloned_from_remote_start_cloning_from_local_mirror() throws IOException, VcsException {
+    VcsRoot root = createVcsRoot(simpleRepo());
+    //clone from remote repository
+    File workingDir = doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null));
+    String hgrcContent = FileUtil.readText(new File(workingDir, ".hg" + File.separator + "hgrc"));
+
+    File workingDir2 = doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null), true);
+    File newMirrorDir = FileUtil.getSubDirectories(myMirrorsRootDir).get(0);
+    String hgrcContent2 = FileUtil.readText(new File(workingDir2, ".hg" + File.separator + "hgrc"));
+    assertFalse(hgrcContent2.equals(hgrcContent));//repository settings are changed
+    assertTrue(hgrcContent2.contains("default = " + newMirrorDir.getCanonicalPath()));//now it clones from local mirror
+  }
+
+  public void repository_cloned_from_local_mirror_start_cloning_from_remote() throws IOException, VcsException {
+    VcsRoot root = createVcsRoot(simpleRepo());
+    //clone from remote repository
+    File workingDir = doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null), true);
+    String hgrcContent = FileUtil.readText(new File(workingDir, ".hg" + File.separator + "hgrc"));
+    File newMirrorDir = FileUtil.getSubDirectories(myMirrorsRootDir).get(0);
+    assertTrue(hgrcContent.contains("default = " + newMirrorDir.getCanonicalPath()));//now it clones from local mirror
+
+    File workingDir2 = doUpdate(root, "3:9522278aa38d", new IncludeRule(".", ".", null));
+    String hgrcContent2 = FileUtil.readText(new File(workingDir2, ".hg" + File.separator + "hgrc"));
+    assertFalse(hgrcContent2.equals(hgrcContent));//repository settings are changed
+    assertTrue(hgrcContent2.contains("default = " + root.getProperty(Constants.REPOSITORY_PROP)));//now it clones from remote
+  }
+
+  /**
+   * TW-15984
+   */
+  public void should_be_able_to_clone_into_non_empty_dir() throws IOException, VcsException {
+    VcsRoot vcsRoot = createVcsRoot(simpleRepo());
+    doUpdate(vcsRoot, "3:9522278aa38d", new IncludeRule(".", "subdir", null));
+    doUpdate(vcsRoot, "4:b06a290a363b", new IncludeRule(".", ".", null));
+  }
+
+  public void cloned_repo_should_contains_default_parameter_in_hgrc() throws VcsException, IOException {
+    VcsRoot root = createVcsRoot(simpleRepo());
+    File workingDir = doUpdate(root, "4:b06a290a363b", new IncludeRule(".", ".", null));
+    File hgrc = new File(workingDir, ".hg" + File.separator + "hgrc");
+    String hgrcContent = FileUtil.readText(hgrc);
+    assertTrue(hgrcContent.contains("default = " + root.getProperty(Constants.REPOSITORY_PROP)));
+  }
+
+  protected String getTestDataPath() {
+    return "mercurial-tests/testData";
+  }
+}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/BaseMercurialTestCase.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/BaseMercurialTestCase.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,74 +1,74 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
-
-import jetbrains.buildServer.MockSupport;
-import jetbrains.buildServer.TempFiles;
-import jetbrains.buildServer.vcs.impl.VcsRootImpl;
-import jetbrains.buildServer.vcs.patches.PatchTestCase;
-import org.jetbrains.annotations.NotNull;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * @author Pavel.Sher
- *         Date: 31.07.2008
- */
-public abstract class BaseMercurialTestCase extends PatchTestCase {
-  protected TempFiles myTempFiles;
-  protected MockSupport myMockSupport;
-
-  @Override
-  @BeforeMethod
-  protected void setUp() throws Exception {
-    super.setUp();
-
-    myMockSupport = new MockSupport();
-    myMockSupport.setUpMocks();
-    myTempFiles = new TempFiles();
-  }
-
-  @AfterMethod
-  protected void tearDown() throws Exception {
-    myMockSupport.tearDownMocks();
-    myTempFiles.cleanup();
-  }
-
-  protected VcsRootImpl createVcsRoot(@NotNull String repPath) throws IOException {
-    VcsRootImpl vcsRoot = new VcsRootImpl(1, Constants.VCS_NAME);
-    vcsRoot.addProperty(Constants.HG_COMMAND_PATH_PROP, new File(Util.getHgPath()).getAbsolutePath());
-    File repository = LocalRepositoryUtil.prepareRepository(repPath);
-    vcsRoot.addProperty(Constants.REPOSITORY_PROP, repository.getAbsolutePath());
-    return vcsRoot;
-  }
-
-  protected VcsRootImpl createVcsRoot(@NotNull String repPath, @NotNull String branchName) throws IOException {
-    VcsRootImpl vcsRoot = createVcsRoot(repPath);
-    vcsRoot.addProperty(Constants.BRANCH_NAME_PROP, branchName);
-    return vcsRoot;
-  }
-
-  protected void cleanRepositoryAfterTest(@NotNull String repPath) {
-    LocalRepositoryUtil.forgetRepository(repPath);
-  }
-
-  protected String simpleRepo() {
-    return new File("mercurial-tests/testData/rep1").getAbsolutePath();
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import jetbrains.buildServer.MockSupport;
+import jetbrains.buildServer.TempFiles;
+import jetbrains.buildServer.vcs.impl.VcsRootImpl;
+import jetbrains.buildServer.vcs.patches.PatchTestCase;
+import org.jetbrains.annotations.NotNull;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Pavel.Sher
+ *         Date: 31.07.2008
+ */
+public abstract class BaseMercurialTestCase extends PatchTestCase {
+  protected TempFiles myTempFiles;
+  protected MockSupport myMockSupport;
+
+  @Override
+  @BeforeMethod
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    myMockSupport = new MockSupport();
+    myMockSupport.setUpMocks();
+    myTempFiles = new TempFiles();
+  }
+
+  @AfterMethod
+  protected void tearDown() throws Exception {
+    myMockSupport.tearDownMocks();
+    myTempFiles.cleanup();
+  }
+
+  protected VcsRootImpl createVcsRoot(@NotNull String repPath) throws IOException {
+    VcsRootImpl vcsRoot = new VcsRootImpl(1, Constants.VCS_NAME);
+    vcsRoot.addProperty(Constants.HG_COMMAND_PATH_PROP, new File(Util.getHgPath()).getAbsolutePath());
+    File repository = LocalRepositoryUtil.prepareRepository(repPath);
+    vcsRoot.addProperty(Constants.REPOSITORY_PROP, repository.getAbsolutePath());
+    return vcsRoot;
+  }
+
+  protected VcsRootImpl createVcsRoot(@NotNull String repPath, @NotNull String branchName) throws IOException {
+    VcsRootImpl vcsRoot = createVcsRoot(repPath);
+    vcsRoot.addProperty(Constants.BRANCH_NAME_PROP, branchName);
+    return vcsRoot;
+  }
+
+  protected void cleanRepositoryAfterTest(@NotNull String repPath) {
+    LocalRepositoryUtil.forgetRepository(repPath);
+  }
+
+  protected String simpleRepo() {
+    return new File("mercurial-tests/testData/rep1").getAbsolutePath();
+  }
+}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/LocalRepositoryUtil.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/LocalRepositoryUtil.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,57 +1,57 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
-
-import jetbrains.buildServer.TempFiles;
-import jetbrains.buildServer.util.FileUtil;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author Pavel.Sher
- *         Date: 14.07.2008
- */
-public class LocalRepositoryUtil {
-  private final static TempFiles myTempFiles = new TempFiles();
-  private final static Map<String, File> myRepositories = new HashMap<String, File>();
-  static {
-    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
-      public void run() {
-        myTempFiles.cleanup();
-      }
-    }));
-  }
-
-  public static File prepareRepository(@NotNull String repPath) throws IOException {
-    File repository = myRepositories.get(repPath);
-    if (repository != null) return repository;
-    final File tempDir = myTempFiles.createTempDir();
-    FileUtil.copyDir(new File(repPath), tempDir);
-    if (new File(tempDir, "hg").isDirectory()) {
-      FileUtil.rename(new File(tempDir, "hg"), new File(tempDir, ".hg"));
-    }
-    myRepositories.put(repPath, tempDir);
-    return tempDir;
-  }
-
-  public static void forgetRepository(@NotNull String repPath) {
-    myRepositories.remove(repPath);
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import jetbrains.buildServer.TempFiles;
+import jetbrains.buildServer.util.FileUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Pavel.Sher
+ *         Date: 14.07.2008
+ */
+public class LocalRepositoryUtil {
+  private final static TempFiles myTempFiles = new TempFiles();
+  private final static Map<String, File> myRepositories = new HashMap<String, File>();
+  static {
+    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+      public void run() {
+        myTempFiles.cleanup();
+      }
+    }));
+  }
+
+  public static File prepareRepository(@NotNull String repPath) throws IOException {
+    File repository = myRepositories.get(repPath);
+    if (repository != null) return repository;
+    final File tempDir = myTempFiles.createTempDir();
+    FileUtil.copyDir(new File(repPath), tempDir);
+    if (new File(tempDir, "hg").isDirectory()) {
+      FileUtil.rename(new File(tempDir, "hg"), new File(tempDir, ".hg"));
+    }
+    myRepositories.put(repPath, tempDir);
+    return tempDir;
+  }
+
+  public static void forgetRepository(@NotNull String repPath) {
+    myRepositories.remove(repPath);
+  }
+}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SettingsTest.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SettingsTest.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,122 +1,122 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
-
-import jetbrains.buildServer.TempFiles;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.Settings;
-import jetbrains.buildServer.vcs.impl.VcsRootImpl;
-import junit.framework.TestCase;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-/**
- * @author Pavel.Sher
- */
-@Test
-public class SettingsTest extends TestCase {
-
-  private TempFiles myTempFiles = new TempFiles();
-  private MirrorManager myMirrorManager;
-
-  @Override
-  @BeforeMethod
-  public void setUp() throws Exception {
-    myMirrorManager = new MirrorManager(myTempFiles.createTempDir());
-  }
-
-  @Override
-  @AfterMethod
-  public void tearDown() throws Exception {
-    myTempFiles.cleanup();
-  }
-
-  public void test_url_without_credentials() {
-    VcsRootImpl vcsRoot = createVcsRoot("http://host.com/path");
-    Settings settings = new Settings(vcsRoot);
-    assertEquals("http://user:pwd@host.com/path", settings.getRepositoryUrl());
-  }
-
-  public void test_url_with_credentials() {
-    VcsRootImpl vcsRoot = createVcsRoot("http://user:pwd@host.com/path");
-    Settings settings = new Settings(vcsRoot);
-    assertEquals("http://user:pwd@host.com/path", settings.getRepositoryUrl());
-  }
-
-  public void test_url_with_username() {
-    VcsRootImpl vcsRoot = createVcsRoot("http://user@host.com/path");
-    Settings settings = new Settings(vcsRoot);
-    assertEquals("http://user:pwd@host.com/path", settings.getRepositoryUrl());
-  }
-
-  public void test_url_with_at_after_slash() {
-    VcsRootImpl vcsRoot = createVcsRoot("http://host.com/path@");
-    Settings settings = new Settings(vcsRoot);
-    assertEquals("http://user:pwd@host.com/path@", settings.getRepositoryUrl());
-  }
-
-  public void test_url_with_at_in_username() {
-    VcsRootImpl vcsRoot = createVcsRoot("http://host.com/path", "my.name@gmail.com", "1234");
-    Settings settings = new Settings(vcsRoot);
-    assertEquals("http://my.name%40gmail.com:1234@host.com/path", settings.getRepositoryUrl());
-  }
-
-  /** TW-13768 */
-  public void test_underscore_in_host() {
-		VcsRootImpl vcsRoot = createVcsRoot("http://Klekovkin.SDK_GARANT:8000/", "my.name@gmail.com", "1234");
-    Settings settings = new Settings(vcsRoot);
-		assertEquals("http://my.name%40gmail.com:1234@Klekovkin.SDK_GARANT:8000/", settings.getRepositoryUrl());
-	}
-
-  /** TW-13768 */
-  public void test_underscore_in_host_with_credentials_in_url() {
-    VcsRootImpl vcsRoot = createVcsRoot("http://me:mypass@Klekovkin.SDK_GARANT:8000/");
-    Settings settings = new Settings(vcsRoot);
-		assertEquals("http://me:mypass@Klekovkin.SDK_GARANT:8000/", settings.getRepositoryUrl());
-  }
-
-  public void test_windows_path() throws Exception {
-    VcsRootImpl vcsRoot = createVcsRoot("c:\\windows\\path");
-    Settings settings = new Settings(vcsRoot);
-    assertEquals("c:\\windows\\path", settings.getRepositoryUrl());
-  }
-
-  public void test_file_scheme_has_no_credentials() {
-    VcsRootImpl vcsRoot = createVcsRoot("file:///path/to/repo", "my.name@gmail.com", "1234");
-    Settings settings = new Settings(vcsRoot);
-    assertEquals("file:///path/to/repo", settings.getRepositoryUrl());
-  }
-
-  public void uncompressed_transfer() {
-    VcsRootImpl root = createVcsRoot("http://host.com/path");
-    root.addProperty(Constants.UNCOMPRESSED_TRANSFER, "true");
-    Settings settings = new Settings(root);
-    assertTrue(settings.isUncompressedTransfer());
-  }
-
-  private VcsRootImpl createVcsRoot(String url) {
-    return createVcsRoot(url, "user", "pwd");
-  }
-
-  private VcsRootImpl createVcsRoot(String url, String userName, String password) {
-    VcsRootImpl vcsRoot = new VcsRootImpl(1, Constants.VCS_NAME);
-    vcsRoot.addProperty(Constants.HG_COMMAND_PATH_PROP, "hg.exe");
-    vcsRoot.addProperty(Constants.REPOSITORY_PROP, url);
-    vcsRoot.addProperty(Constants.USERNAME, userName);
-    vcsRoot.addProperty(Constants.PASSWORD, password);
-    return vcsRoot;
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial;
+
+import jetbrains.buildServer.TempFiles;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.Settings;
+import jetbrains.buildServer.vcs.impl.VcsRootImpl;
+import junit.framework.TestCase;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * @author Pavel.Sher
+ */
+@Test
+public class SettingsTest extends TestCase {
+
+  private TempFiles myTempFiles = new TempFiles();
+  private MirrorManager myMirrorManager;
+
+  @Override
+  @BeforeMethod
+  public void setUp() throws Exception {
+    myMirrorManager = new MirrorManager(myTempFiles.createTempDir());
+  }
+
+  @Override
+  @AfterMethod
+  public void tearDown() throws Exception {
+    myTempFiles.cleanup();
+  }
+
+  public void test_url_without_credentials() {
+    VcsRootImpl vcsRoot = createVcsRoot("http://host.com/path");
+    Settings settings = new Settings(vcsRoot);
+    assertEquals("http://user:pwd@host.com/path", settings.getRepositoryUrl());
+  }
+
+  public void test_url_with_credentials() {
+    VcsRootImpl vcsRoot = createVcsRoot("http://user:pwd@host.com/path");
+    Settings settings = new Settings(vcsRoot);
+    assertEquals("http://user:pwd@host.com/path", settings.getRepositoryUrl());
+  }
+
+  public void test_url_with_username() {
+    VcsRootImpl vcsRoot = createVcsRoot("http://user@host.com/path");
+    Settings settings = new Settings(vcsRoot);
+    assertEquals("http://user:pwd@host.com/path", settings.getRepositoryUrl());
+  }
+
+  public void test_url_with_at_after_slash() {
+    VcsRootImpl vcsRoot = createVcsRoot("http://host.com/path@");
+    Settings settings = new Settings(vcsRoot);
+    assertEquals("http://user:pwd@host.com/path@", settings.getRepositoryUrl());
+  }
+
+  public void test_url_with_at_in_username() {
+    VcsRootImpl vcsRoot = createVcsRoot("http://host.com/path", "my.name@gmail.com", "1234");
+    Settings settings = new Settings(vcsRoot);
+    assertEquals("http://my.name%40gmail.com:1234@host.com/path", settings.getRepositoryUrl());
+  }
+
+  /** TW-13768 */
+  public void test_underscore_in_host() {
+		VcsRootImpl vcsRoot = createVcsRoot("http://Klekovkin.SDK_GARANT:8000/", "my.name@gmail.com", "1234");
+    Settings settings = new Settings(vcsRoot);
+		assertEquals("http://my.name%40gmail.com:1234@Klekovkin.SDK_GARANT:8000/", settings.getRepositoryUrl());
+	}
+
+  /** TW-13768 */
+  public void test_underscore_in_host_with_credentials_in_url() {
+    VcsRootImpl vcsRoot = createVcsRoot("http://me:mypass@Klekovkin.SDK_GARANT:8000/");
+    Settings settings = new Settings(vcsRoot);
+		assertEquals("http://me:mypass@Klekovkin.SDK_GARANT:8000/", settings.getRepositoryUrl());
+  }
+
+  public void test_windows_path() throws Exception {
+    VcsRootImpl vcsRoot = createVcsRoot("c:\\windows\\path");
+    Settings settings = new Settings(vcsRoot);
+    assertEquals("c:\\windows\\path", settings.getRepositoryUrl());
+  }
+
+  public void test_file_scheme_has_no_credentials() {
+    VcsRootImpl vcsRoot = createVcsRoot("file:///path/to/repo", "my.name@gmail.com", "1234");
+    Settings settings = new Settings(vcsRoot);
+    assertEquals("file:///path/to/repo", settings.getRepositoryUrl());
+  }
+
+  public void uncompressed_transfer() {
+    VcsRootImpl root = createVcsRoot("http://host.com/path");
+    root.addProperty(Constants.UNCOMPRESSED_TRANSFER, "true");
+    Settings settings = new Settings(root);
+    assertTrue(settings.isUncompressedTransfer());
+  }
+
+  private VcsRootImpl createVcsRoot(String url) {
+    return createVcsRoot(url, "user", "pwd");
+  }
+
+  private VcsRootImpl createVcsRoot(String url, String userName, String password) {
+    VcsRootImpl vcsRoot = new VcsRootImpl(1, Constants.VCS_NAME);
+    vcsRoot.addProperty(Constants.HG_COMMAND_PATH_PROP, "hg.exe");
+    vcsRoot.addProperty(Constants.REPOSITORY_PROP, url);
+    vcsRoot.addProperty(Constants.USERNAME, userName);
+    vcsRoot.addProperty(Constants.PASSWORD, password);
+    return vcsRoot;
+  }
+}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommandTestCase.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommandTestCase.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,96 +1,96 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import jetbrains.buildServer.BaseTestCase;
-import jetbrains.buildServer.TempFiles;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.Constants;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.LocalRepositoryUtil;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.MirrorManager;
-import jetbrains.buildServer.buildTriggers.vcs.mercurial.Util;
-import jetbrains.buildServer.vcs.VcsException;
-import jetbrains.buildServer.vcs.VcsRoot;
-import jetbrains.buildServer.vcs.impl.VcsRootImpl;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-public class BaseCommandTestCase extends BaseTestCase {
-  private String myRepository;
-  private String myUsername;
-  private String myPassword;
-  private boolean myCloneRequired;
-
-  public BaseCommandTestCase() {
-  }
-
-  protected void setRepository(final String repository, boolean cloneRequired) {
-    myRepository = repository;
-    myCloneRequired = cloneRequired;
-  }
-
-  protected void setUsername(final String username) {
-    myUsername = username;
-  }
-
-  protected void setPassword(final String password) {
-    myPassword = password;
-  }
-
-  protected <T> T runCommand(CommandExecutor<T> executor) throws IOException, VcsException {
-    Map<String, String> vcsRootProps = new HashMap<String, String>();
-
-    vcsRootProps.put(Constants.REPOSITORY_PROP, myRepository);
-
-    if (myCloneRequired) {
-      File repository = LocalRepositoryUtil.prepareRepository(new File(myRepository).getAbsolutePath());
-      vcsRootProps.put(Constants.REPOSITORY_PROP, repository.getAbsolutePath());
-    }
-
-    vcsRootProps.put(Constants.HG_COMMAND_PATH_PROP, Util.getHgPath());
-    if (myUsername != null) {
-      vcsRootProps.put(Constants.USERNAME, myUsername);
-    }
-    if (myPassword != null) {
-      vcsRootProps.put(Constants.PASSWORD, myPassword);
-    }
-
-    TempFiles tf = new TempFiles();
-    File parentDir = tf.createTempDir();
-
-    MirrorManager mirrorManager = new MirrorManager(parentDir);
-    VcsRoot vcsRoot = new VcsRootImpl(1, vcsRootProps);
-    Settings settings = new Settings(vcsRoot);
-    final File workingDir = mirrorManager.getMirrorDir(settings.getRepositoryUrl());
-    settings.setCustomWorkingDir(workingDir);
-    try {
-      if (myCloneRequired) {
-        new CloneCommand(settings, workingDir).execute();
-      }
-
-      return executor.execute(settings, workingDir);
-    } finally {
-      tf.cleanup();
-    }
-  }
-
-  public interface CommandExecutor<T> {
-    T execute(@NotNull Settings settings, File workingDir) throws VcsException;
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import jetbrains.buildServer.BaseTestCase;
+import jetbrains.buildServer.TempFiles;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.Constants;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.LocalRepositoryUtil;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.MirrorManager;
+import jetbrains.buildServer.buildTriggers.vcs.mercurial.Util;
+import jetbrains.buildServer.vcs.VcsException;
+import jetbrains.buildServer.vcs.VcsRoot;
+import jetbrains.buildServer.vcs.impl.VcsRootImpl;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class BaseCommandTestCase extends BaseTestCase {
+  private String myRepository;
+  private String myUsername;
+  private String myPassword;
+  private boolean myCloneRequired;
+
+  public BaseCommandTestCase() {
+  }
+
+  protected void setRepository(final String repository, boolean cloneRequired) {
+    myRepository = repository;
+    myCloneRequired = cloneRequired;
+  }
+
+  protected void setUsername(final String username) {
+    myUsername = username;
+  }
+
+  protected void setPassword(final String password) {
+    myPassword = password;
+  }
+
+  protected <T> T runCommand(CommandExecutor<T> executor) throws IOException, VcsException {
+    Map<String, String> vcsRootProps = new HashMap<String, String>();
+
+    vcsRootProps.put(Constants.REPOSITORY_PROP, myRepository);
+
+    if (myCloneRequired) {
+      File repository = LocalRepositoryUtil.prepareRepository(new File(myRepository).getAbsolutePath());
+      vcsRootProps.put(Constants.REPOSITORY_PROP, repository.getAbsolutePath());
+    }
+
+    vcsRootProps.put(Constants.HG_COMMAND_PATH_PROP, Util.getHgPath());
+    if (myUsername != null) {
+      vcsRootProps.put(Constants.USERNAME, myUsername);
+    }
+    if (myPassword != null) {
+      vcsRootProps.put(Constants.PASSWORD, myPassword);
+    }
+
+    TempFiles tf = new TempFiles();
+    File parentDir = tf.createTempDir();
+
+    MirrorManager mirrorManager = new MirrorManager(parentDir);
+    VcsRoot vcsRoot = new VcsRootImpl(1, vcsRootProps);
+    Settings settings = new Settings(vcsRoot);
+    final File workingDir = mirrorManager.getMirrorDir(settings.getRepositoryUrl());
+    settings.setCustomWorkingDir(workingDir);
+    try {
+      if (myCloneRequired) {
+        new CloneCommand(settings, workingDir).execute();
+      }
+
+      return executor.execute(settings, workingDir);
+    } finally {
+      tf.cleanup();
+    }
+  }
+
+  public interface CommandExecutor<T> {
+    T execute(@NotNull Settings settings, File workingDir) throws VcsException;
+  }
+}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommandTest.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommandTest.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,97 +1,97 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-@Test
-public class LogCommandTest extends BaseCommandTestCase {
-  @BeforeMethod
-  @Override
-  protected void setUp() throws Exception {
-    super.setUp();
-    setRepository("mercurial-tests/testData/rep1", true);
-  }
-
-  public void testOneChangeSet() throws Exception {
-    final String toId = "9875b412a788";
-    List<ChangeSet> changes = runLog(null, toId);
-    assertEquals(1, changes.size());
-    final ChangeSet changeSet = changes.get(0);
-    assertEquals(0, changeSet.getRevNumber());
-    assertEquals(toId, changeSet.getId());
-    assertEquals("pavel@localhost", changeSet.getUser());
-    assertEquals("dir1 created", changeSet.getDescription());
-    assertNull(changeSet.getParents());
-  }
-
-  public void testMoreThanOneChangeSet() throws Exception {
-    final String fromId = "9875b412a788";
-    final String toId = "7209b1f1d793";
-    List<ChangeSet> changes = runLog(fromId, toId);
-    assertEquals(3, changes.size());
-    ChangeSet changeSet1 = changes.get(0);
-    final ChangeSet changeSet2 = changes.get(1);
-    final ChangeSet changeSet3 = changes.get(2);
-    assertEquals("dir1 created", changeSet1.getDescription());
-    assertEquals("new file added", changeSet2.getDescription());
-    assertEquals("file4.txt added", changeSet3.getDescription());
-
-    changes = runLog(null, toId);
-    assertEquals(3, changes.size());
-    changeSet1 = changes.get(2);
-    assertEquals("file4.txt added", changeSet1.getDescription());
-  }
-
-  public void changeset_parents() throws VcsException, IOException {
-    setRepository("mercurial-tests/testData/rep2", true);
-    List<ChangeSet> changes = runLog("6eeb8974fe67", "6eeb8974fe67");
-    assertEquals(1, changes.size());
-    ChangeSet cs = changes.get(0);
-    assertNotNull(cs.getParents());
-    assertEquals(2, cs.getParents().size());
-    assertTrue(cs.getParents().contains(new ChangeSetRevision("1:a3d15477d297")));
-    assertTrue(cs.getParents().contains(new ChangeSetRevision("3:2538c02bafeb")));
-  }
-
-  public void parse_multiline_description() throws VcsException, IOException {
-    List<ChangeSet> changes = runLog("9babcf2d5705", "9c6a6b4aede0");
-    assertEquals(1, changes.size());
-    assertEquals("Multiline description\n" +
-            "description with new\n" +
-            "lines\n" +
-            "aaaa\n" +
-            "bbb", changes.get(0).getDescription());
-  }
-
-  private List<ChangeSet> runLog(final String fromId, final String toId) throws IOException, VcsException {
-    return runCommand(new CommandExecutor<List<ChangeSet>>() {
-      public List<ChangeSet> execute(@NotNull final Settings settings, @NotNull File workingDir) throws VcsException {
-        LogCommand lc = new LogCommand(settings, workingDir);
-        lc.setFromRevId(fromId);
-        lc.setToRevId(toId);
-        return lc.execute();
-      }
-    });
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+@Test
+public class LogCommandTest extends BaseCommandTestCase {
+  @BeforeMethod
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    setRepository("mercurial-tests/testData/rep1", true);
+  }
+
+  public void testOneChangeSet() throws Exception {
+    final String toId = "9875b412a788";
+    List<ChangeSet> changes = runLog(null, toId);
+    assertEquals(1, changes.size());
+    final ChangeSet changeSet = changes.get(0);
+    assertEquals(0, changeSet.getRevNumber());
+    assertEquals(toId, changeSet.getId());
+    assertEquals("pavel@localhost", changeSet.getUser());
+    assertEquals("dir1 created", changeSet.getDescription());
+    assertNull(changeSet.getParents());
+  }
+
+  public void testMoreThanOneChangeSet() throws Exception {
+    final String fromId = "9875b412a788";
+    final String toId = "7209b1f1d793";
+    List<ChangeSet> changes = runLog(fromId, toId);
+    assertEquals(3, changes.size());
+    ChangeSet changeSet1 = changes.get(0);
+    final ChangeSet changeSet2 = changes.get(1);
+    final ChangeSet changeSet3 = changes.get(2);
+    assertEquals("dir1 created", changeSet1.getDescription());
+    assertEquals("new file added", changeSet2.getDescription());
+    assertEquals("file4.txt added", changeSet3.getDescription());
+
+    changes = runLog(null, toId);
+    assertEquals(3, changes.size());
+    changeSet1 = changes.get(2);
+    assertEquals("file4.txt added", changeSet1.getDescription());
+  }
+
+  public void changeset_parents() throws VcsException, IOException {
+    setRepository("mercurial-tests/testData/rep2", true);
+    List<ChangeSet> changes = runLog("6eeb8974fe67", "6eeb8974fe67");
+    assertEquals(1, changes.size());
+    ChangeSet cs = changes.get(0);
+    assertNotNull(cs.getParents());
+    assertEquals(2, cs.getParents().size());
+    assertTrue(cs.getParents().contains(new ChangeSetRevision("1:a3d15477d297")));
+    assertTrue(cs.getParents().contains(new ChangeSetRevision("3:2538c02bafeb")));
+  }
+
+  public void parse_multiline_description() throws VcsException, IOException {
+    List<ChangeSet> changes = runLog("9babcf2d5705", "9c6a6b4aede0");
+    assertEquals(1, changes.size());
+    assertEquals("Multiline description\n" +
+            "description with new\n" +
+            "lines\n" +
+            "aaaa\n" +
+            "bbb", changes.get(0).getDescription());
+  }
+
+  private List<ChangeSet> runLog(final String fromId, final String toId) throws IOException, VcsException {
+    return runCommand(new CommandExecutor<List<ChangeSet>>() {
+      public List<ChangeSet> execute(@NotNull final Settings settings, @NotNull File workingDir) throws VcsException {
+        LogCommand lc = new LogCommand(settings, workingDir);
+        lc.setFromRevId(fromId);
+        lc.setToRevId(toId);
+        return lc.execute();
+      }
+    });
+  }
+}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PushCommandTest.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/PushCommandTest.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,48 +1,48 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-import org.testng.annotations.Test;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * @author Pavel.Sher
- */
-@Test
-public class PushCommandTest extends BaseCommandTestCase {
-  public void hide_private_data() throws VcsException, IOException {
-    setRepository("http://some.host.com", false);
-    setUsername("user1");
-    final String password = "pwd1";
-    setPassword(password);
-
-    try {
-      runCommand(new CommandExecutor<Boolean>() {
-        public Boolean execute(@NotNull final Settings settings, @NotNull File workingDir) throws VcsException {
-          PushCommand cmd = new PushCommand(settings, workingDir);
-          cmd.execute();
-          return null;
-        }
-      });
-    } catch (VcsException e) {
-      assertFalse(e.getMessage().contains(password));
-    }
-  }
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Pavel.Sher
+ */
+@Test
+public class PushCommandTest extends BaseCommandTestCase {
+  public void hide_private_data() throws VcsException, IOException {
+    setRepository("http://some.host.com", false);
+    setUsername("user1");
+    final String password = "pwd1";
+    setPassword(password);
+
+    try {
+      runCommand(new CommandExecutor<Boolean>() {
+        public Boolean execute(@NotNull final Settings settings, @NotNull File workingDir) throws VcsException {
+          PushCommand cmd = new PushCommand(settings, workingDir);
+          cmd.execute();
+          return null;
+        }
+      });
+    } catch (VcsException e) {
+      assertFalse(e.getMessage().contains(password));
+    }
+  }
+}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/StatusCommandTest.java	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/StatusCommandTest.java	Wed Jul 20 12:04:08 2011 +0400
@@ -1,66 +1,66 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
-
-import jetbrains.buildServer.vcs.VcsException;
-import org.jetbrains.annotations.NotNull;
-import org.testng.annotations.Test;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-@Test
-public class StatusCommandTest extends BaseCommandTestCase {
-  public void testAddedFile() throws IOException, VcsException {
-    setRepository("mercurial-tests/testData/rep1", true);
-    List<ModifiedFile> files = runStatus("9875b412a788", "1d446e82d356");
-    assertEquals(1, files.size());
-    ModifiedFile md = files.get(0);
-    assertEquals(ModifiedFile.Status.ADDED, md.getStatus());
-    assertEquals("dir1/file3.txt", md.getPath().replace(File.separatorChar, '/'));
-  }
-
-  public void testRemovedFile() throws IOException, VcsException {
-    setRepository("mercurial-tests/testData/rep1", true);
-    List<ModifiedFile> files = runStatus("7209b1f1d793", "9522278aa38d");
-    assertEquals(1, files.size());
-    ModifiedFile md = files.get(0);
-    assertEquals(ModifiedFile.Status.REMOVED, md.getStatus());
-    assertEquals("dir1/file4.txt", md.getPath().replace(File.separatorChar, '/'));
-  }
-
-  public void testModifiedFile() throws IOException, VcsException {
-    setRepository("mercurial-tests/testData/rep1", true);
-    List<ModifiedFile> files = runStatus("9522278aa38d", "b06a290a363b");
-    assertEquals(1, files.size());
-    ModifiedFile md = files.get(0);
-    assertEquals(ModifiedFile.Status.MODIFIED, md.getStatus());
-    assertEquals("dir1/file3.txt", md.getPath().replace(File.separatorChar, '/'));
-  }
-
-  private List<ModifiedFile> runStatus(final String fromId, final String toId) throws IOException, VcsException {
-    return runCommand(new CommandExecutor<List<ModifiedFile>>() {
-      public List<ModifiedFile> execute(@NotNull final Settings settings, @NotNull final File workingDir) throws VcsException {
-        StatusCommand st = new StatusCommand(settings, workingDir);
-        st.setFromRevId(fromId);
-        st.setToRevId(toId);
-        return st.execute();
-      }
-    });
-  }
-
-}
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed 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 jetbrains.buildServer.buildTriggers.vcs.mercurial.command;
+
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+@Test
+public class StatusCommandTest extends BaseCommandTestCase {
+  public void testAddedFile() throws IOException, VcsException {
+    setRepository("mercurial-tests/testData/rep1", true);
+    List<ModifiedFile> files = runStatus("9875b412a788", "1d446e82d356");
+    assertEquals(1, files.size());
+    ModifiedFile md = files.get(0);
+    assertEquals(ModifiedFile.Status.ADDED, md.getStatus());
+    assertEquals("dir1/file3.txt", md.getPath().replace(File.separatorChar, '/'));
+  }
+
+  public void testRemovedFile() throws IOException, VcsException {
+    setRepository("mercurial-tests/testData/rep1", true);
+    List<ModifiedFile> files = runStatus("7209b1f1d793", "9522278aa38d");
+    assertEquals(1, files.size());
+    ModifiedFile md = files.get(0);
+    assertEquals(ModifiedFile.Status.REMOVED, md.getStatus());
+    assertEquals("dir1/file4.txt", md.getPath().replace(File.separatorChar, '/'));
+  }
+
+  public void testModifiedFile() throws IOException, VcsException {
+    setRepository("mercurial-tests/testData/rep1", true);
+    List<ModifiedFile> files = runStatus("9522278aa38d", "b06a290a363b");
+    assertEquals(1, files.size());
+    ModifiedFile md = files.get(0);
+    assertEquals(ModifiedFile.Status.MODIFIED, md.getStatus());
+    assertEquals("dir1/file3.txt", md.getPath().replace(File.separatorChar, '/'));
+  }
+
+  private List<ModifiedFile> runStatus(final String fromId, final String toId) throws IOException, VcsException {
+    return runCommand(new CommandExecutor<List<ModifiedFile>>() {
+      public List<ModifiedFile> execute(@NotNull final Settings settings, @NotNull final File workingDir) throws VcsException {
+        StatusCommand st = new StatusCommand(settings, workingDir);
+        st.setFromRevId(fromId);
+        st.setToRevId(toId);
+        return st.execute();
+      }
+    });
+  }
+
+}
--- a/mercurial-tests/src/testng.xml	Thu Jul 07 14:11:32 2011 +0400
+++ b/mercurial-tests/src/testng.xml	Wed Jul 20 12:04:08 2011 +0400
@@ -1,17 +1,17 @@
-<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
-<suite name="Mercurial Suite">
-  <test name="Mercurial Tests">
-    <classes>
-      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.BaseCommandTest"/>
-      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CloneCommandTest"/>
-      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.LogCommandTest"/>
-      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.StatusCommandTest"/>
-      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.PushCommandTest"/>
-      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.IdentifyCommandTest"/>
-      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialVcsSupportTest"/>
-      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.AgentSideCheckoutTest"/>
-      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.SettingsTest"/>
-      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.MirrorManagerTest"/>
-    </classes>
-  </test>
-</suite>
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="Mercurial Suite">
+  <test name="Mercurial Tests">
+    <classes>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.BaseCommandTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CloneCommandTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.LogCommandTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.StatusCommandTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.PushCommandTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.IdentifyCommandTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialVcsSupportTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.AgentSideCheckoutTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.SettingsTest"/>
+      <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.MirrorManagerTest"/>
+    </classes>
+  </test>
+</suite>