add trunk dir

git-svn-id: https://svn.apache.org/repos/asf/ant/sandbox/antlibs/vss/trunk@991755 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..ad6a6af
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,6 @@
+   Apache Ant Library for Microsoft Visual Source Safe
+   Copyright 2002-2004,2006 The Apache Software Foundation
+
+   This product includes software developed by
+   The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..25c2727
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+ 
+      http://www.apache.org/licenses/LICENSE-2.0
+ 
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project default="compile" name="vss">
+
+  <!-- easy way to override properties -->
+  <property file="build.properties"/>
+
+  <import file="common/build.xml"/>
+
+  <target name="clean" depends="common.clean">
+    <delete dir="tmpdir"/>
+  </target>
+</project>
\ No newline at end of file
diff --git a/docs/vss.html b/docs/vss.html
new file mode 100644
index 0000000..3a641f0
--- /dev/null
+++ b/docs/vss.html
@@ -0,0 +1,1282 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Microsoft Visual SourceSafe(VSS) Tasks</title>
+</head>
+<body>
+<h1>Microsoft Visual SourceSafe Tasks User Manual</h1>
+<p>by</p>
+<ul>
+    <li>Craig Cottingham</li>
+    <li>Andrew Everitt</li>
+    <li>Balazs Fejes 2</li>
+    <li><a href="mailto:Glenn_Twiggs@bmc.com">Glenn_Twiggs@bmc.com</a></li>
+    <li>Martin Poeschl (<a href="mailto:mpoeschl@marmot.at">mpoeschl@marmot.at</a>)</li>
+    <li>Phillip Wells</li>
+    <li>Jon Skeet (<a href="mailto:jon.skeet@peramon.com">jon.skeet@peramon.com</a>)</li>
+    <li>Nigel Magnay (<a href="mailto:nigel.magnay@parsec.co.uk">nigel.magnay@parsec.co.uk</a>)</li>
+    <li>Gary S. Weaver</li>
+    <li>Jesse Stockall</li>
+ </ul>
+<hr>
+<h2>Contents</h2>
+<ul>
+    <li><a href="#intro">Introduction</a></li>
+    <li><a href="#tasks">The Tasks</a></li>
+</ul>
+<br>
+<h2><a name="intro">Introduction</a></h2>
+<p>This antlib provides an interface to the
+<a href="http://msdn.microsoft.com/ssafe/default.asp" target="_top">Microsoft Visual SourceSafe</a> SCM.
+The original tasks (<code>org.apache.tools.ant.taskdefs.optional.vss</code>) have been expanded upon in this antlib.
+Some fixes to issues in the original tasks have also been incorporated.</p>
+<p>
+If you get a CreateProcesss IOError=2 when running these, it means
+that ss.exe was not found. Check to see if you can run it from the
+command line -you may need to alter your path, or set the <tt>ssdir</tt>
+property.</p>
+<p>
+To use this antlib in your build file, you must first declare it eg:
+<blockquote>
+<pre>
+&lt;project name="myproject" basedir="." 
+         default="test" xmlns:vss="antlib:org.apache.ant.vss"&gt;
+</pre>
+</blockquote>
+
+<h2><a name="tasks">The Tasks</a></h2>
+
+<table border="0" cellspacing="0" cellpadding="3">
+    <tr>
+        <td><a href="#vss:get">vss:get</a></td>
+        <td>Retrieves a copy of the specified VSS file(s).</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:label">vss:label</a></td>
+        <td>Assigns a label to the specified version or current version of a file or project.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:history">vss:history</a></td>
+        <td>Shows the history of a file or project in VSS.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:checkin">vss:checkin</a></td>
+        <td>Updates VSS with changes made to a checked out file, and unlocks the VSS master copy.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:checkout">vss:checkout</a></td>
+        <td>Copies a file from the current project to the current folder, for the purpose of editing.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:add">vss:add</a></td>
+        <td>Adds a new file into the VSS Archive</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:cp">vss:cp</a></td>
+        <td>Change the current project being used in VSS</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:create">vss:create</a></td>
+        <td>Creates a project in VSS.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:destroy">vss:destroy</a></td>
+        <td>Permanently remove a file or project from VSS.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:move">vss:move</a></td>
+        <td>Relocates a subproject from one parent project to another.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:cloak">vss:cloak</a></td>
+        <td>Hides a project from recursive Get, Check Out, Check In, Undo Check Out, and Project Differences commands.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:decloak">vss:decloak</a></td>
+        <td>Removes the cloaked attribute from a project.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:delete">vss:delete</a></td>
+        <td>Removes files and projects from VSS Explorer, and marks them as deleted; the items still exist, however, and can be recovered using the Recover command.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:recover">vss:recover</a></td>
+        <td>Recovers files and projects that have been deleted.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:locate">vss:locate</a></td>
+        <td>Searches through VSS projects for file or project names.</td>
+    </tr>
+    <tr>
+        <td><a href="#vss:status">vss:status</a></td>
+        <td>Shows check out information on files.</td>
+    </tr>
+</table>
+
+<hr>
+<h2>Task Descriptions</h2>
+
+<!-- VSSGET -->
+
+<h2><a name="vss:get">vss:get</a></h2>
+<h3>Description</h3>
+Task to perform GET commands to Microsoft Visual SourceSafe.
+<p>If you specify two or more attributes from version, date and
+label only one will be used in the order version, date, label.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+     <td>vsspath</td>
+     <td>SourceSafe path which specifies the project/file(s) you wish to
+         perform the action on.</td>
+     <td>Yes</td>
+  </tr>
+  <tr>
+     <td>login</td>
+     <td>username[,password] - The username and password needed to get access
+         to VSS. Note that you may need to specify both (if you have a password) -
+         Ant/VSS will hang if you leave the password out and VSS does not accept
+         login without a password. </td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>localpath</td>
+     <td>Override the working directory and get to the specified path</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>ssdir</td>
+     <td>directory where <code>ss.exe</code> resides. By default the
+         task expects it to be in the PATH.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>serverPath</td>
+     <td>directory where <code>srcsafe.ini</code> resides.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>writable</td>
+     <td>true or false; default false</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>recursive</td>
+     <td>true or false; default false. Note however that in the SourceSafe UI
+     , there is a setting accessed via Tools/Options/GeneralTab called
+     &quot;Act on projects recursively&quot;.  If this setting is checked,
+     then the recursive attribute is effectively ignored, and the get
+     will always be done recursively
+     </td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>version</td>
+     <td>a version number to get</td>
+     <td rowspan="3">No, only one of these allowed</td>
+  </tr>
+  <tr>
+     <td>date</td>
+     <td>a date stamp to get at</td>
+  </tr>
+  <tr>
+     <td>label</td>
+     <td>a label to get for</td>
+  </tr>
+  <tr>
+     <td>quiet</td>
+     <td>suppress output (off by default)</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>autoresponse</td>
+     <td>What to respond with (sets the -I option). By default, -I- is
+     used; values of Y or N will be appended to this.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+    <td>writablefiles</td>
+    <td>Behavior when local files are writable. Valid options are: <code>replace</code>, 
+        <code>skip</code> and <code>fail</code>; Defaults to <code>fail</code>
+        <br><code>skip</code> implies <code>failonerror=false</code></td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>failonerror</td>
+    <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>filetimestamp</td>
+    <td>Set the behavior for timestamps of local files. Valid options are <code>current</code>, 
+        <code>modified</code>, or <code>updated</code>. Defaults to <code>current</code>.</td> 
+    <td>No</td>
+  </tr>
+</table>
+<p>Note that only one of version, date or label should be specified</p>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vss:get localPath=&quot;C:\mysrc\myproject&quot;
+        recursive=&quot;true&quot;
+        label=&quot;Release1&quot;
+        login=&quot;me,mypassword&quot;
+        vsspath=&quot;$/source/aProject&quot;
+        writable=&quot;true&quot;/&gt;
+</pre>
+</blockquote>
+<p>Does a get on the VSS-Project <i>$/source/myproject</i> using the username
+<i>me</i> and the password <i>mypassword</i>. It will recursively get the files
+which are labeled <i>Release1</i> and write them to the local directory
+<i>C:\mysrc\myproject</i>. The local files will be writable.</p>
+<hr>
+
+<!-- VSSLABEL -->
+
+<h2><a name="vss:label">vss:label</a></h2>
+<h3>Description</h3>
+Task to perform LABEL commands to Microsoft Visual SourceSafe.
+<p>Assigns a label to the specified version or current version of a file or
+project.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+  <tr>
+     <td>vsspath</td>
+     <td>SourceSafe path which specifies the project/file(s) you wish to
+         perform the action on.</td>
+     <td>Yes</td>
+  </tr>
+  <tr>
+     <td>login</td>
+     <td>username[,password] - The username and password needed to get access
+         to VSS. Note that you may need to specify both (if you have a password) -
+         Ant/VSS will hang if you leave the password out and VSS does not accept
+         login without a password. </td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>ssdir</td>
+     <td>directory where <code>ss.exe</code> resides. By default the
+         task expects it to be in the PATH.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>serverPath</td>
+     <td>directory where <code>srcsafe.ini</code> resides.</td>
+     <td>No</td>
+  </tr>
+   <tr>
+      <td>label</td>
+      <td>A label to apply to the hierarchy</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>version</td>
+      <td>An existing file or project version to label. By default the current
+      version is labeled.</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>comment</td>
+      <td>The comment to use for this label. Empty or '-' for no comment.</td>
+      <td>No</td>
+   </tr>
+  <tr>
+     <td>autoresponse</td>
+     <td>What to respond with (sets the -I option). By default, -I- is
+     used; values of Y or N will be appended to this.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+    <td>failonerror</td>
+    <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+    <td>No</td>
+  </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vss:label vsspath=&quot;$/source/aProject&quot;
+          login=&quot;me,mypassword&quot;
+          label=&quot;Release1&quot;/&gt;
+</pre>
+</blockquote>
+<p>Labels the current version of the VSS project <i>$/source/aProject</i> with
+the label <i>Release1</i> using the username <i>me</i> and the password
+<i>mypassword</i>.
+</p>
+<blockquote>
+<pre>
+&lt;vss:label vsspath=&quot;$/source/aProject/myfile.txt&quot;
+          version=&quot;4&quot;
+          label=&quot;1.03.004&quot;/&gt;
+</pre>
+</blockquote>
+<p>Labels version 4 of the VSS file <i>$/source/aProject/myfile.txt</i> with the
+label <i>1.03.004</i>. If this version already has a label, the operation (and
+the build) will fail.
+</p>
+<hr>
+
+<!-- VSSHISTORY -->
+
+<h2><a name="vss:history">vss:history</a></h2>
+<h3>Description</h3>
+Task to perform HISTORY commands to Microsoft Visual SourceSafe.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+     <td>vsspath</td>
+     <td>SourceSafe path which specifies the project/file(s) you wish to
+         perform the action on.</td>
+     <td>Yes</td>
+  </tr>
+  <tr>
+     <td>login</td>
+     <td>username[,password] - The username and password needed to get access
+         to VSS. Note that you may need to specify both (if you have a password) -
+         Ant/VSS will hang if you leave the password out and VSS does not accept
+         login without a password. </td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>ssdir</td>
+     <td>directory where <code>ss.exe</code> resides. By default the
+         task expects it to be in the PATH.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>serverPath</td>
+     <td>directory where <code>srcsafe.ini</code> resides.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+    <td>fromDate</td>
+    <td>Start date for comparison</td>
+    <td>See below</td>
+  </tr>
+  <tr>
+    <td>toDate</td>
+    <td>End date for comparison</td>
+    <td>See below</td>
+  </tr>
+  <tr>
+    <td>dateFormat</td>
+    <td>Format of dates in fromDate and toDate. Used when calculating dates with
+      the numdays attribute. This string uses the formatting rules of SimpleDateFormat.
+      Defaults to DateFormat.SHORT.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>fromLabel</td>
+    <td>Start label for comparison</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>toLabel</td>
+    <td>Start label for comparison</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>numdays</td>
+    <td>The number of days for comparison.</td>
+    <td>See below</td>
+  </tr>
+  <tr>
+    <td>output</td>
+    <td>File to write the diff.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>recursive</td>
+    <td>true or false</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>style</td>
+    <td>brief, codediff, default or nofile. The default is default.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>user</td>
+    <td>Name the user whose changes we would like to see</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>failonerror</td>
+    <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+    <td>No</td>
+  </tr>
+</table>
+
+<h4>Specifying the time-frame</h4>
+<p>There are different ways to specify what time-frame you wish to evaluate:</p>
+<ul>
+  <li>Changes between two dates: Specify both <code>fromDate</code> and <code>toDate</code> </li>
+  <li>Changes before a date: Specify <code>toDate</code></li>
+  <li>Changes after a date: Specify <code>fromDate</code></li>
+  <li>Changes X Days before a date: Specify <code>toDate</code> and (negative!) <code>numDays</code></li>
+  <li>Changes X Days after a date: Specify <code>fromDate</code> and <code>numDays</code></li>
+</ul>
+
+
+<h3>Examples</h3>
+<blockquote>
+  <pre>
+&lt;vss:history vsspath=&quot;$/myProject&quot; recursive=&quot;true&quot;
+            fromLabel=&quot;Release1&quot;
+            toLabel=&quot;Release2&quot;/&gt;
+</pre>
+</blockquote>
+<p>Shows all changes between &quot;Release1&quot; and &quot;Release2&quot;.</p>
+
+<blockquote>
+  <pre>
+&lt;vss:history vsspath=&quot;$/myProject&quot; recursive=&quot;true&quot;
+            fromDate=&quot;01.01.2001&quot;
+            toDate=&quot;31.03.2001&quot;/&gt;
+</pre>
+</blockquote>
+<p>Shows all changes between January 1st 2001 and March 31st 2001 (in Germany, date must be specified according to your locale).</p>
+
+<blockquote>
+  <pre>
+&lt;tstamp&gt;
+  &lt;format property=&quot;to.tstamp&quot; pattern=&quot;M-d-yy;h:mma&quot;/&gt;
+&lt;/tstamp&gt;
+
+&lt;vss:history vsspath=&quot;$/myProject&quot; recursive=&quot;true&quot;
+            numDays=&quot;-14&quot;
+            dateFormat=&quot;M-d-yy;h:mma&quot;
+            toDate=&quot;${to.tstamp}&quot;/&gt;
+</pre>
+</blockquote>
+<p>Shows all changes in the 14 days before today.</p>
+<hr>
+
+<!-- VSSCHECKIN -->
+
+<h2><a name="vss:checkin">vss:checkin</a></h2>
+<h3>Description</h3>
+Task to perform CHECKIN commands to Microsoft Visual SourceSafe.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+     <td>vsspath</td>
+     <td>SourceSafe path which specifies the project/file(s) you wish to
+         perform the action on.</td>
+     <td>Yes</td>
+  </tr>
+  <tr>
+     <td>login</td>
+     <td>username[,password] - The username and password needed to get access
+         to VSS. Note that you may need to specify both (if you have a password) -
+         Ant/VSS will hang if you leave the password out and VSS does not accept
+         login without a password. </td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>localpath</td>
+     <td>Override the working directory and get to the specified path</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>ssdir</td>
+     <td>directory where <code>ss.exe</code> resides. By default the
+         task expects it to be in the PATH.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>serverPath</td>
+     <td>directory where <code>srcsafe.ini</code> resides.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>writable</td>
+     <td>true or false</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>recursive</td>
+     <td>true or false</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>comment</td>
+     <td>Comment to use for the files that where checked in.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>autoresponse</td>
+     <td>'Y', 'N' or empty. Specify how to reply to questions from VSS.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+    <td>failonerror</td>
+    <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+    <td>No</td>
+  </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vss:checkin vsspath=&quot;$/test/test*&quot;
+            localpath=&quot;D:\build\&quot;
+            comment=&quot;Modified by automatic build&quot;/&gt;
+</pre>
+</blockquote>
+<p>Checks in the file(s) named <i>test*</i> in the project <i>$/test</i> using
+the local directory <i>D:\build</i>.</p>
+<hr>
+
+<!-- VSSCHECKOUT -->
+
+<h2><a name="vss:checkout">vss:checkout</a></h2>
+<h3>Description</h3>
+Task to perform CHECKOUT commands to Microsoft Visual SourceSafe.
+<p>If you specify two or more attributes from version, date and
+label only one will be used in the order version, date, label.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+     <td>vsspath</td>
+     <td>SourceSafe path which specifies the project/file(s) you wish to
+         perform the action on.</td>
+     <td>Yes</td>
+  </tr>
+  <tr>
+     <td>login</td>
+     <td>username[,password] - The username and password needed to get access
+         to VSS. Note that you may need to specify both (if you have a password) -
+         Ant/VSS will hang if you leave the password out and VSS does not accept
+         login without a password. </td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>localpath</td>
+     <td>Override the working directory and get to the specified path</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>ssdir</td>
+     <td>directory where <code>ss.exe</code> resides. By default the
+         task expects it to be in the PATH.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>serverPath</td>
+     <td>directory where <code>srcsafe.ini</code> resides.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>writable</td>
+     <td>true or false</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>recursive</td>
+     <td>true or false</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>version</td>
+     <td>a version number to get</td>
+     <td rowspan="3">No, only one of these allowed</td>
+  </tr>
+  <tr>
+     <td>date</td>
+     <td>a date stamp to get at</td>
+  </tr>
+  <tr>
+     <td>label</td>
+     <td>a label to get for</td>
+  </tr>
+  <tr>
+    <td>writablefiles</td>
+    <td>Behavior when local files are writable. Valid options are: <code>replace</code>, 
+        <code>skip</code> and <code>fail</code>; Defaults to <code>fail</code>
+        <br><code>skip</code> implies <code>failonerror=false</code></td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>failonerror</td>
+    <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>filetimestamp</td>
+    <td>Set the behavior for timestamps of local files. Valid options are <code>current</code>, 
+        <code>modified</code>, or <code>updated</code>. Defaults to <code>current</code>.</td> 
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>getlocalcopy</td>
+    <td>Set the behavior to retrieve local copies of the files. Defaults to true.</td> 
+    <td>No</td>
+  </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vss:checkout vsspath=&quot;$/test&quot;
+             localpath=&quot;D:\build&quot;
+             recursive=&quot;true&quot;
+             login=&quot;me,mypass&quot;/&gt;
+</pre>
+</blockquote>
+<p>Does a recursive checkout of the project <i>$/test</i> to the directory D:\build.
+</p>
+<hr>
+
+<!-- VSSADD -->
+
+<h2><a name="vss:add">vss:add</a></h2>
+<h3>Description</h3>
+Task to perform ADD commands to Microsoft Visual SourceSafe.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+     <td>localpath</td>
+     <td>Specify the local file(s) to add to VSS</td>
+     <td>Yes</td>
+  </tr>
+  <tr>
+     <td>login</td>
+     <td>username[,password] - The username and password needed to get access
+         to VSS. Note that you may need to specify both (if you have a password) -
+         Ant/VSS will hang if you leave the password out and VSS does not accept
+         login without a password. </td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>ssdir</td>
+     <td>directory where <code>ss.exe</code> resides. By default the
+         task expects it to be in the PATH.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>serverPath</td>
+     <td>directory where <code>srcsafe.ini</code> resides.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>writable</td>
+     <td>true or false</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>recursive</td>
+     <td>true or false</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>comment</td>
+     <td>Comment to use for the files that where checked in.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>autoresponse</td>
+     <td>'Y', 'N' or empty. Specify how to reply to questions from VSS.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+    <td>failonerror</td>
+    <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+    <td>No</td>
+  </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vss:add localpath=&quot;D:\build\build.00012.zip&quot;
+            comment=&quot;Added by automatic build&quot;/&gt;
+</pre>
+</blockquote>
+<p>Add the file named build.00012.zip into the project current working
+directory (see vsscp).</p>
+<hr>
+
+<!-- VSSCP -->
+
+<h2><a name="vss:cp">vss:cp</a></h2>
+<h3>Description</h3>
+<p>Task to perform CP (Change Project) commands to Microsoft Visual SourceSafe.</p>
+<p>This task is typically used before a VssAdd in order to set the target project</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+     <td>vsspath</td>
+     <td>SourceSafe path which specifies the project you wish to
+         make the current project.</td>
+     <td>Yes</td>
+  </tr>
+  <tr>
+     <td>login</td>
+     <td>username[,password] - The username and password needed to get access
+         to VSS. Note that you may need to specify both (if you have a password) -
+         Ant/VSS will hang if you leave the password out and VSS does not accept
+         login without a password. </td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>ssdir</td>
+     <td>directory where <code>ss.exe</code> resides. By default the
+         task expects it to be in the PATH.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+     <td>serverPath</td>
+     <td>directory where <code>srcsafe.ini</code> resides.</td>
+     <td>No</td>
+  </tr>
+  <tr>
+    <td>failonerror</td>
+    <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+    <td>No</td>
+  </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vss:cp vsspath=&quot;$/Projects/ant&quot;/&gt;
+</pre>
+</blockquote>
+<p>Sets the current VSS project to <i>$/Projects/ant</i>.</p>
+<hr>
+
+<!-- VSSCREATE -->
+
+ <h2><a name="vss:create">vss:create</a></h2>
+ <h3>Description</h3>
+ Task to perform CREATE commands to Microsoft Visual Source Safe.
+ <p>Creates a new project in VSS.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+    <td>login</td>
+    <td>username,password</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>vsspath</td>
+    <td>SourceSafe path of project to be created</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>ssdir</td>
+    <td>directory where <code>ss.exe</code> resides. By default the task expects it to be in the PATH.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>quiet</td>
+    <td>suppress output (off by default)</td>
+    <td>No</td>
+   </tr>
+  <tr>
+    <td>failOnError</td>
+    <td>fail if there is an error creating the project (true by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>autoresponse</td>
+    <td>What to respond with (sets the -I option). By default, -I- is used; values of Y or N will be appended to this.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>comment</td>
+    <td>The comment to use for this label. Empty or '-' for no comment.</td>
+    <td>No</td>
+  </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vss:create vsspath=&quot;$/existingProject/newProject&quot;/&gt;
+</pre>
+</blockquote>
+<p>Creates the VSS-Project <i>$/existingProject/newProject</i>.</p>
+<!-- vss:destroy -->
+ <h2><a name="vss:destroy">vss:destroy</a></h2>
+ <h3>Description</h3>
+ Task to perform DESTROY commands to Microsoft Visual Source Safe.
+ <p>Permanently removes a project or file in VSS.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+    <td>login</td>
+    <td>username,password</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>vsspath</td>
+    <td>SourceSafe path of project to be removed</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>ssdir</td>
+    <td>directory where <code>ss.exe</code> resides. By default the task expects it to be in the PATH.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>quiet</td>
+    <td>suppress output (off by default)</td>
+    <td>No</td>
+   </tr>
+  <tr>
+    <td>failOnError</td>
+    <td>fail if there is an error creating the project (true by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>autoresponse</td>
+    <td>What to respond with (sets the -I option). By default, -I- is used; values of Y or N will be appended to this.</td>
+    <td>No</td>
+  </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vss:destroy vsspath=&quot;$/existingProject/oldProject&quot;/&gt;
+</pre>
+</blockquote>
+<p>Permanently removes the VSS-Project <i>$/existingProject/oldProject</i>.</p>
+
+<!-- vss:move -->
+ <h2><a name="vss:move">vss:move</a></h2>
+ <h3>Description</h3>
+ Task to perform MOVE commands to Microsoft Visual Source Safe.
+ <p>Moves a project or file in VSS.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+    <td>login</td>
+    <td>username,password</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>vsspath</td>
+    <td>SourceSafe path of project to be moved</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>ssdir</td>
+    <td>directory where <code>ss.exe</code> resides. By default the task expects it to be in the PATH.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>quiet</td>
+    <td>suppress output (off by default)</td>
+    <td>No</td>
+   </tr>
+  <tr>
+    <td>failOnError</td>
+    <td>fail if there is an error creating the project (true by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>autoresponse</td>
+    <td>What to respond with (sets the -I option). By default, -I- is used; values of Y or N will be appended to this.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>destination</td>
+    <td>location in VSS to move project specified by vsspath to.</td>
+    <td>Yes</td>
+  </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+ &lt;vss:move
+  	  vsspath="$/${vss-project}/sub2"
+	  destination="$/${vss-project}/sub1"
+  	  login="Guest,"
+  	/&gt;
+</pre>
+</blockquote>
+<p>Moves the VSS-Project <i>$/${vss-project}/sub2</i> to <i>$/${vss-project}/sub1/sub2</i>.</p>
+
+<!-- vss:cloak -->
+ <h2><a name="vss:cloak">vss:cloak</a></h2>
+ <h3>Description</h3>
+ Task to perform CLOAK commands to Microsoft Visual Source Safe.
+ <p>Hides a project from recursive Get, Check Out, Check In, Undo Check Out, and Project Differences commands.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+    <td>login</td>
+    <td>username,password</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>vsspath</td>
+    <td>SourceSafe path of project to be cloaked</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>ssdir</td>
+    <td>directory where <code>ss.exe</code> resides. By default the task expects it to be in the PATH.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>quiet</td>
+    <td>suppress output (off by default)</td>
+    <td>No</td>
+   </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+ &lt;vss:cloak
+  	  vsspath="$/${vss-project}"
+  	  login="Guest,"
+  	/&gt;
+</pre>
+</blockquote>
+<p>Cloaks the VSS-Project <i>$/${vss-project}</i>.</p>
+
+<!-- vss:decloak -->
+ <h2><a name="vss:decloak">vss:decloak</a></h2>
+ <h3>Description</h3>
+ Task to perform DECLOAK commands to Microsoft Visual Source Safe.
+ <p>Removes the cloaked attribute from a project.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+    <td>login</td>
+    <td>username,password</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>vsspath</td>
+    <td>SourceSafe path of project to be decloaked</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>ssdir</td>
+    <td>directory where <code>ss.exe</code> resides. By default the task expects it to be in the PATH.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>quiet</td>
+    <td>suppress output (off by default)</td>
+    <td>No</td>
+   </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+ &lt;vss:decloak
+  	  vsspath="$/${vss-project}"
+  	  login="Guest,"
+  	/&gt;
+</pre>
+</blockquote>
+<p>Decloaks the VSS-Project <i>$/${vss-project}</i>.</p>
+
+<!-- vss:delete -->
+ <h2><a name="vss:delete">vss:delete</a></h2>
+ <h3>Description</h3>
+ Task to perform DELETE commands to Microsoft Visual Source Safe.
+ <p>Removes files and projects from VSS Explorer, and marks them as deleted; the items still exist, however, and can be recovered using the Recover command.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+    <td>login</td>
+    <td>username,password</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>vsspath</td>
+    <td>SourceSafe path of project or file to be deleted</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>ssdir</td>
+    <td>directory where <code>ss.exe</code> resides. By default the task expects it to be in the PATH.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>quiet</td>
+    <td>suppress output (off by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>failOnError</td>
+    <td>fail if there is an error creating the project (true by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>autoresponse</td>
+    <td>What to respond with (sets the -I option). By default, -I- is used; values of Y or N will be appended to this.</td>
+    <td>No</td>
+  </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+ &lt;vss:delete
+  	  vsspath="$/${vss-project}"
+  	  login="Guest,"
+  	/&gt;
+</pre>
+</blockquote>
+<p>Deletes the VSS-Project <i>$/${vss-project}</i>.</p>
+
+<!-- vss:recover -->
+ <h2><a name="vss:recover">vss:recover</a></h2>
+ <h3>Description</h3>
+ Task to perform RECOVER commands to Microsoft Visual Source Safe.
+ <p>Recovers files and projects that have been deleted.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+    <td>login</td>
+    <td>username,password</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>vsspath</td>
+    <td>SourceSafe path of project or file to be recovered</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>ssdir</td>
+    <td>directory where <code>ss.exe</code> resides. By default the task expects it to be in the PATH.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>quiet</td>
+    <td>suppress output (off by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>failOnError</td>
+    <td>fail if there is an error creating the project (true by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>autoresponse</td>
+    <td>What to respond with (sets the -I option). By default, -I- is used; values of Y or N will be appended to this.</td>
+    <td>No</td>
+  </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+ &lt;vss:recover
+  	  vsspath="$/${vss-project}"
+  	  login="Guest,"
+  	/&gt;
+</pre>
+</blockquote>
+<p>Recovers the VSS-Project <i>$/${vss-project}</i>.</p>
+
+<!-- vss:locate -->
+ <h2><a name="vss:locate">vss:locate</a></h2>
+ <h3>Description</h3>
+ Task to perform LOCATE commands to Microsoft Visual Source Safe.
+ <p>Locates files and projects in VSS.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+    <td>login</td>
+    <td>username,password</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>vsspath</td>
+    <td>SourceSafe path of project or file to be recovered</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>ssdir</td>
+    <td>directory where <code>ss.exe</code> resides. By default the task expects it to be in the PATH.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>quiet</td>
+    <td>suppress output (off by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>failOnError</td>
+    <td>fail if there is an error creating the project (true by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>autoresponse</td>
+    <td>What to respond with (sets the -I option). By default, -I- is used; values of Y or N will be appended to this.</td>
+    <td>No</td>
+  </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+ &lt;vss:locate
+  	  vsspath="$/${vss-project}"
+  	  login="Guest,"
+  	/&gt;
+</pre>
+</blockquote>
+<p>Locates the VSS-Project <i>$/${vss-project}</i>.</p>
+
+<!-- vss:status -->
+ <h2><a name="vss:status">vss:status</a></h2>
+ <h3>Description</h3>
+ Task to perform STATUS commands to Microsoft Visual Source Safe.
+ <p>Shows check out information on files VSS.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <th>Attribute</th>
+    <th>Values</th>
+    <th>Required</th>
+  </tr>
+  <tr>
+    <td>login</td>
+    <td>username,password</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>user</td>
+    <td>The user to search for files for.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>vsspath</td>
+    <td>SourceSafe path of project or file to be recovered</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>ssdir</td>
+    <td>directory where <code>ss.exe</code> resides. By default the task expects it to be in the PATH.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>quiet</td>
+    <td>suppress output (off by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>failOnError</td>
+    <td>fail if there is an error creating the project (true by default)</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>autoresponse</td>
+    <td>What to respond with (sets the -I option). By default, -I- is used; values of Y or N will be appended to this.</td>
+    <td>No</td>
+  </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+ &lt;vss:status
+	  vsspath=&quot;$/${vss-project}&quot;
+	  login=&quot;Guest,&quot;
+      user=&quot;Guest&quot;
+	/&gt;
+</pre>
+</blockquote>
+<p>Locates the VSS-Project <i>$/${vss-project}</i>.</p>
+<hr>
+
+<!-- Footer -->
+</body>
+</html>
diff --git a/src/etc/testcases/msvss.xml b/src/etc/testcases/msvss.xml
new file mode 100644
index 0000000..48404ac
--- /dev/null
+++ b/src/etc/testcases/msvss.xml
@@ -0,0 +1,227 @@
+<?xml version="1.0"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<project name="msvss-test" basedir="../../../"
+         default="test-all" xmlns:vss="antlib:org.apache.ant.vss">
+
+  <property name="file" value="build.xml"/>
+  <property name="vss-project" value="antlib"/>
+  <property name="testcase-dir" value="${basedir}/src/etc/testcases"/>
+  <property name="testing-dir" value="${basedir}/testing"/>
+  <property environment="env" />
+
+  <presetdef name="sscreate">
+    <vss:create
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+      login="Guest,"
+    />
+  </presetdef>
+
+  <presetdef name="sscp">
+    <vss:cp
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+      login="Guest,"
+    />
+  </presetdef>
+
+  <presetdef name="ssadd">
+    <vss:add
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+      login="Guest,"
+    />
+  </presetdef>
+
+  <macrodef name="create-tempfile">
+    <attribute name="property" />
+    <attribute name="directory" default="${testing-dir}" />
+    <attribute name="message" default="Testing VSS"/>
+    <sequential>
+      <mkdir dir="@{directory}" />
+      <tempfile property="@{property}" destdir="@{directory}"
+          suffix=".java" />
+      <echo file="${@{property}}" message="// @{message}" />
+    </sequential>
+  </macrodef>
+
+  <target name="setup" depends="find-ss-server-dir, find-ss-dir">
+    <fail unless="vss-ss-dir">Could not find ss.exe.
+        Add to Path environment variable
+        or add vss-ss-dir=[path to ss.exe] to build.properties
+        or add -Dvss-ss-dir=[path to ss.exe] to command line.</fail>
+    <fail unless="vss-server-dir">Could not find SourceSafe Database.
+        Add SSDIR to environment
+        or add vss-server-dir=[path to database] to build.properties
+        or add -Dvss-server-dir=[path to database] to command line.</fail>
+    <sscreate
+      vsspath="$/${vss-project}"
+    />
+    <sscp
+      vsspath="$/${vss-project}"
+    />
+  </target>
+
+  <target name="find-ss-server-dir" unless="vss-server-dir">
+    <available property="vss-server-dir" file="srcsafe.ini"
+        filepath="${env.SSDIR}" value="${env.SSDIR}" />
+    <available property="vss-server-dir" file="srcsafe.ini"
+        filepath="${env.Ssdir}" value="${env.Ssdir}" />
+    <available property="vss-server-dir" file="srcsafe.ini"
+        filepath="${env.ssdir}" value="${env.ssdir}" />
+  </target>
+
+  <target name="find-ss-dir" depends="find-ss-exe" if="vss-ss-exe"
+      unless="vss-ss-dir">
+    <dirname property="vss-ss-dir" file="${vss-ss-exe}" />
+  </target>
+
+  <target name="find-ss-exe" unless="vss-ss-exe">
+    <available property="vss-ss-exe" file="ss.exe" filepath="${env.Path}"
+        value="ss.exe" />
+    <available property="vss-ss-exe"
+        file="C:\Program Files\Microsoft Visual Sourcesafe\ss.exe"
+        value="C:\Program Files\Microsoft Visual Sourcesafe\ss.exe" />
+    <available property="vss-ss-exe"
+        file="C:\Program Files (x86)\Microsoft Visual Sourcesafe\ss.exe"
+        value="C:\Program Files (x86)\Microsoft Visual Sourcesafe\ss.exe"/>
+  </target>
+
+
+  <target name="test-all" depends="setup, test-delete-recover, test-add,
+      test-move, test-cloak, test-locate, test-status, test-checkout, test-checkin"
+      description="Test all VSS tasks other than destroy (use cleanup for that)"
+  />
+
+  <target name="test-add" depends="setup">
+    <create-tempfile property="vss-temp-file" message="Testing Add for VSS" />
+    <ssadd
+      vsspath="$/${vss-project}"
+      localpath="${vss-temp-file}"
+      comment="Testing Add for VSS"
+    />
+  </target>
+
+  <target name="test-move" depends="setup">
+    <!-- create sub projects -->
+    <sscreate
+      vsspath="$/${vss-project}/sub1"
+    />
+
+    <sscreate
+      vsspath="$/${vss-project}/sub2"
+    />
+
+    <!-- perform move operation -->
+    <vss:move
+      vsspath="$/${vss-project}/sub2"
+      destination="$/${vss-project}/sub1"
+      login="Guest,"
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+    />
+  </target>
+
+  <target name="test-cloak" depends="setup">
+    <vss:cloak
+      vsspath="$/${vss-project}"
+      login="Guest,"
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+    />
+    <vss:decloak
+      vsspath="$/${vss-project}"
+      login="Guest,"
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+    />
+  </target>
+
+  <target name="test-delete-recover" depends="setup">
+    <vss:delete
+      vsspath="$/${vss-project}"
+      login="Guest,"
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+    />
+    <vss:recover
+      vsspath="$/${vss-project}"
+      login="Guest,"
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+    />
+    <!-- should be able to change to project as it has been 'recovered' -->
+    <sscp
+      vsspath="$/${vss-project}"
+    />
+  </target>
+
+  <target name="test-locate" depends="setup">
+    <vss:locate
+      vsspath="$/${vss-project}"
+      login="Guest,"
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+    />
+  </target>
+
+  <target name="test-status" depends="setup">
+    <vss:status
+      vsspath="$/${vss-project}"
+      login="Guest,"
+      user="Guest"
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+    />
+  </target>
+
+  <target name="test-checkout" depends="setup, test-add">
+    <vss:checkout
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+      vsspath="$/${vss-project}"
+      localpath="${testing-dir}"
+      login="Guest,"
+    />
+  </target>
+
+  <target name="test-checkin" depends="setup, test-checkout">
+    <echo file="${vss-temp-file}" message="Testing Checkin with VSS" />
+    <vss:checkin
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+      vsspath="$/${vss-project}"
+      localpath="${testing-dir}"
+      login="Guest,"
+      comment="Testing Checkin with VSS"
+    />
+  </target>
+
+  <target name="cleanup" depends="find-ss-server-dir, find-ss-dir">
+    <vss:destroy
+      vsspath="$/${vss-project}"
+      login="Guest,"
+      autoresponse="Y"
+      ssdir="${vss-ss-dir}"
+      serverPath="${vss-server-dir}"
+    />
+    <delete dir="${testing-dir}" />
+  </target>
+</project>
\ No newline at end of file
diff --git a/src/main/org/apache/ant/vss/MSVSS.java b/src/main/org/apache/ant/vss/MSVSS.java
new file mode 100644
index 0000000..7fe1de7
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSS.java
@@ -0,0 +1,691 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import java.io.File;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * A base class for creating tasks for executing commands on Visual SourceSafe.
+ * <p>
+ * The class extends the 'exec' task as it operates by executing the ss.exe program
+ * supplied with SourceSafe. By default the task expects ss.exe to be in the path,
+ * you can override this be specifying the ssdir attribute.
+ * </p>
+ * <p>
+ * This class provides set and get methods for 'login' and 'vsspath' attributes. It
+ * also contains constants for the flags that can be passed to SS.
+ * </p>
+ *
+ */
+public abstract class MSVSS extends Task implements MSVSSConstants {
+
+    private String ssDir = null;
+    private String vssLogin = null;
+    private String vssPath = null;
+    private String serverPath = null;
+
+    /**  Version */
+    private String version = null;
+    /**  Date */
+    private String date = null;
+    /**  Label */
+    private String label = null;
+    /**  Auto response */
+    private String autoResponse = null;
+    /**  Local path */
+    private String localPath = null;
+    /**  Comment */
+    private String comment = null;
+    /**  From label */
+    private String fromLabel = null;
+    /**  To label */
+    private String toLabel = null;
+    /**  Output file name */
+    private String outputFileName = null;
+    /**  User */
+    private String user = null;
+    /**  From date */
+    private String fromDate = null;
+    /**  To date */
+    private String toDate = null;
+    /**  History style */
+    private String style = null;
+    /**  Quiet defaults to false */
+    private boolean quiet = false;
+    /**  Recursive defaults to false */
+    private boolean recursive = false;
+    /**  Writable defaults to false */
+    private boolean writable = false;
+    /**  Fail on error defaults to true */
+    private boolean failOnError = true;
+    /**  Get local copy for checkout defaults to true */
+    private boolean getLocalCopy = true;
+    /**  Number of days offset for History */
+    private int numDays = Integer.MIN_VALUE;
+    /**  Date format for History */
+    private DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
+    /**  Timestamp for retreived files */
+    private CurrentModUpdated timestamp = null;
+    /**  Behaviour for writable files */
+    private WritableFiles writableFiles = null;
+    /**
+     * Each sub-class must implemnt this method and return the constructed
+     * command line to be executed. It is up to the sub-task to determine the
+     * required attrubutes and their order.
+     * @return    The Constructed command line.
+     */
+    abstract Commandline buildCmdLine();
+
+    /**
+     * Directory where <code>ss.exe</code> resides.
+     * By default the task expects it to be in the PATH.
+     * @param  dir  The directory containing ss.exe.
+     */
+    public final void setSsdir(String dir) {
+        this.ssDir = FileUtils.translatePath(dir);
+    }
+
+    /**
+     * Login to use when accessing VSS, formatted as "username,password".
+     * <p>
+     * You can omit the password if your database is not password protected.
+     * If you have a password and omit it, Ant will hang.
+     * @param  vssLogin  The login string to use.
+     */
+    public final void setLogin(final String vssLogin) {
+        this.vssLogin = vssLogin;
+    }
+
+    /**
+     * SourceSafe path which specifies the project/file(s) you wish to perform
+     * the action on.
+     * <p>
+     * A prefix of 'vss://' will be removed if specified.
+     * @param  vssPath  The VSS project path.
+     * @ant.attribute group="required"
+     */
+    public final void setVsspath(final String vssPath) {
+        String projectPath;
+        if (vssPath.startsWith("vss://")) { //$NON-NLS-1$
+            projectPath = vssPath.substring(5);
+        } else {
+            projectPath = vssPath;
+        }
+
+        if (projectPath.startsWith(PROJECT_PREFIX)) {
+            this.vssPath = projectPath;
+        } else {
+            this.vssPath = PROJECT_PREFIX + projectPath;
+        }
+    }
+
+    /**
+     * Directory where <code>srssafe.ini</code> resides.
+     * @param  serverPath  The path to the VSS server.
+     */
+    public final void setServerpath(final String serverPath) {
+        this.serverPath = serverPath;
+    }
+
+    /**
+     * Indicates if the build should fail if the Sourcesafe command does. Defaults to true.
+     * @param failOnError True if task should fail on any error.
+     */
+    public final void setFailOnError(final boolean failOnError) {
+        this.failOnError = failOnError;
+    }
+
+    /**
+     * Executes the task. <br>
+     * Builds a command line to execute ss.exe and then calls Exec's run method
+     * to execute the command line.
+     * @throws BuildException if the command cannot execute.
+     */
+    public void execute() throws BuildException {
+        int result = 0;
+        Commandline commandLine = buildCmdLine();
+        result = run(commandLine);
+        if (Execute.isFailure(result) && getFailOnError()) {
+            String msg = "Failed executing: " + formatCommandLine(commandLine)
+                     + " With a return code of " + result;
+            throw new BuildException(msg, getLocation());
+        }
+    }
+
+    // Special setters for the sub-classes
+
+    protected void setInternalComment(final String comment) {
+        this.comment = comment;
+    }
+
+    protected void setInternalAutoResponse(final String autoResponse) {
+        this.autoResponse = autoResponse;
+    }
+
+    protected void setInternalDate(final String date) {
+        this.date = date;
+    }
+
+    protected void setInternalDateFormat(final DateFormat dateFormat) {
+        this.dateFormat = dateFormat;
+    }
+
+    protected void setInternalFailOnError(final boolean failOnError) {
+        this.failOnError = failOnError;
+    }
+
+    protected void setInternalFromDate(final String fromDate) {
+        this.fromDate = fromDate;
+    }
+
+    protected void setInternalFromLabel(final String fromLabel) {
+        this.fromLabel = fromLabel;
+    }
+
+    protected void setInternalLabel(final String label) {
+        this.label = label;
+    }
+
+    protected void setInternalLocalPath(final String localPath) {
+        this.localPath = localPath;
+    }
+
+    protected void setInternalNumDays(final int numDays) {
+        this.numDays = numDays;
+    }
+
+    protected void setInternalOutputFilename(final String outputFileName) {
+        this.outputFileName = outputFileName;
+    }
+
+    protected void setInternalQuiet(final boolean quiet) {
+        this.quiet = quiet;
+    }
+
+    protected void setInternalRecursive(final boolean recursive) {
+        this.recursive = recursive;
+    }
+
+    protected void setInternalStyle(final String style) {
+        this.style = style;
+    }
+
+    protected void setInternalToDate(final String toDate) {
+        this.toDate = toDate;
+    }
+
+    protected void setInternalToLabel(final String toLabel) {
+        this.toLabel = toLabel;
+    }
+
+    protected void setInternalUser(final String user) {
+        this.user = user;
+    }
+
+    protected void setInternalVersion(final String version) {
+        this.version = version;
+    }
+
+    protected void setInternalWritable(final boolean writable) {
+        this.writable = writable;
+    }
+
+    protected void setInternalFileTimeStamp(final CurrentModUpdated timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    protected void setInternalWritableFiles(final WritableFiles writableFiles) {
+        this.writableFiles = writableFiles;
+    }
+
+    protected void setInternalGetLocalCopy(final boolean getLocalCopy) {
+        this.getLocalCopy = getLocalCopy;
+    }
+
+    /**
+     * Gets the sscommand string. "ss" or "c:\path\to\ss"
+     * @return    The path to ss.exe or just ss if sscommand is not set.
+     */
+    protected String getSSCommand() {
+        if (ssDir == null) {
+            return SS_EXE;
+        }
+        return ssDir.endsWith(File.separator) ? ssDir + SS_EXE : ssDir
+                 + File.separator + SS_EXE;
+    }
+
+    /**
+     * Gets the vssserverpath string.
+     * @return    null if vssserverpath is not set.
+     */
+    protected String getVsspath() {
+        return vssPath;
+    }
+
+    /**
+     * Gets the quiet string. -O-
+     * @return An empty string if quiet is not set or is false.
+     */
+    protected String getQuiet() {
+        return quiet ? FLAG_QUIET : "";
+    }
+
+    /**
+     * Gets the recursive string. "-R"
+     * @return An empty string if recursive is not set or is false.
+     */
+    protected String getRecursive() {
+        return recursive ? FLAG_RECURSION : "";
+    }
+
+    /**
+     * Gets the writable string. "-W"
+     * @return An empty string if writable is not set or is false.
+     */
+    protected String getWritable() {
+        return writable ? FLAG_WRITABLE : "";
+    }
+
+    /**
+     * Gets the label string. "-Lbuild1"
+     * Max label length is 32 chars
+     * @return An empty string if label is not set.
+     */
+    protected String getLabel() {
+        String shortLabel = "";
+        if (label != null && label.length() > 0) {
+                shortLabel = FLAG_LABEL + getShortLabel();
+        }
+        return shortLabel;
+    }
+    /**
+     * Return at most the 30 first chars of the label,
+     * logging a warning message about the truncation
+     * @return at most the 30 first chars of the label
+     */
+    private String getShortLabel() {
+        String shortLabel;
+        if (label !=  null && label.length() > 31) {
+            shortLabel = this.label.substring(0, 30);
+            log("Label is longer than 31 characters, truncated to: " + shortLabel,
+                Project.MSG_WARN);
+        } else {
+            shortLabel = label;
+        }
+        return shortLabel;
+    }
+    /**
+     * Gets the style string. "-Lbuild1"
+     * @return An empty string if label is not set.
+     */
+    protected String getStyle() {
+        return style != null ? style : "";
+    }
+
+    /**
+     * Gets the version string. Returns the first specified of version "-V1.0",
+     * date "-Vd01.01.01", label "-Vlbuild1".
+     * @return An empty string if a version, date and label are not set.
+     */
+    protected String getVersionDateLabel() {
+        String versionDateLabel = "";
+        if (version != null) {
+            versionDateLabel = FLAG_VERSION + version;
+        } else if (date != null) {
+            versionDateLabel = FLAG_VERSION_DATE + date;
+        } else {
+            // Use getShortLabel() so labels longer then 30 char are truncated
+            // and the user is warned
+            String shortLabel = getShortLabel();
+            if (shortLabel != null && !shortLabel.equals("")) {
+                versionDateLabel = FLAG_VERSION_LABEL + shortLabel;
+            }
+        }
+        return versionDateLabel;
+    }
+
+    /**
+     * Gets the version string.
+     * @return An empty string if a version is not set.
+     */
+    protected String getVersion() {
+        return version != null ? FLAG_VERSION + version : "";
+    }
+
+    /**
+     * Gets the localpath string. "-GLc:\source" <p>
+     * The localpath is created if it didn't exist.
+     * @return An empty string if localpath is not set.
+     */
+    protected String getLocalpath() {
+        String lclPath = ""; //set to empty str if no local path return
+        if (localPath != null) {
+            //make sure m_LocalDir exists, create it if it doesn't
+            File dir = getProject().resolveFile(localPath);
+            if (!dir.exists()) {
+                boolean done = dir.mkdirs();
+                if (!done) {
+                    String msg = "Directory " + localPath + " creation was not "
+                            + "successful for an unknown reason";
+                    throw new BuildException(msg, getLocation());
+                }
+                getProject().log("Created dir: " + dir.getAbsolutePath());
+            }
+            lclPath = FLAG_OVERRIDE_WORKING_DIR + localPath;
+        }
+        return lclPath;
+    }
+
+    /**
+     * Gets the comment string. "-Ccomment text"
+     * @return A comment of "-" if comment is not set.
+     */
+    protected String getComment() {
+        return comment != null ? FLAG_COMMENT + comment : FLAG_COMMENT + "-";
+    }
+
+    /**
+     * Gets the auto response string. This can be Y "-I-Y" or N "-I-N".
+     * @return The default value "-I-" if autoresponse is not set.
+     */
+    protected String getAutoresponse() {
+        if (autoResponse == null) {
+            return FLAG_AUTORESPONSE_DEF;
+        } else if (autoResponse.equalsIgnoreCase("Y")) {
+            return FLAG_AUTORESPONSE_YES;
+        } else if (autoResponse.equalsIgnoreCase("N")) {
+            return FLAG_AUTORESPONSE_NO;
+        } else {
+            return FLAG_AUTORESPONSE_DEF;
+        }
+    }
+
+    /**
+     * Gets the login string. This can be user and password, "-Yuser,password"
+     * or just user "-Yuser".
+     * @return An empty string if login is not set.
+     */
+    protected String getLogin() {
+        return vssLogin != null ? FLAG_LOGIN + vssLogin : "";
+    }
+
+    /**
+     * Gets the output file string. "-Ooutput.file"
+     * @return An empty string if user is not set.
+     */
+    protected String getOutput() {
+        return outputFileName != null ? FLAG_OUTPUT + outputFileName : "";
+    }
+
+    /**
+     * Gets the user string. "-Uusername"
+     * @return An empty string if user is not set.
+     */
+    protected String getUser() {
+        return user != null ? FLAG_USER + user : "";
+    }
+
+    /**
+     * Gets the version string. This can be to-from "-VLbuild2~Lbuild1", from
+     * "~Lbuild1" or to "-VLbuild2".
+     * @return An empty string if neither tolabel or fromlabel are set.
+     */
+    protected String getVersionLabel() {
+        if (fromLabel == null && toLabel == null) {
+            return "";
+        }
+        if (fromLabel != null && toLabel != null) {
+            if (fromLabel.length() > 31) {
+                fromLabel = fromLabel.substring(0, 30);
+                log("FromLabel is longer than 31 characters, truncated to: "
+                    + fromLabel, Project.MSG_WARN);
+            }
+            if (toLabel.length() > 31) {
+                toLabel = toLabel.substring(0, 30);
+                log("ToLabel is longer than 31 characters, truncated to: "
+                    + toLabel, Project.MSG_WARN);
+            }
+            return FLAG_VERSION_LABEL + toLabel + VALUE_FROMLABEL + fromLabel;
+        } else if (fromLabel != null) {
+            if (fromLabel.length() > 31) {
+                fromLabel = fromLabel.substring(0, 30);
+                log("FromLabel is longer than 31 characters, truncated to: "
+                    + fromLabel, Project.MSG_WARN);
+            }
+            return FLAG_VERSION + VALUE_FROMLABEL + fromLabel;
+        } else {
+            if (toLabel.length() > 31) {
+                toLabel = toLabel.substring(0, 30);
+                log("ToLabel is longer than 31 characters, truncated to: "
+                    + toLabel, Project.MSG_WARN);
+            }
+            return FLAG_VERSION_LABEL + toLabel;
+        }
+    }
+
+    /**
+     * Gets the Version date string.
+     * @return An empty string if neither Todate or from date are set.
+     * @throws BuildException
+     */
+    protected String getVersionDate() throws BuildException {
+        if (fromDate == null && toDate == null
+            && numDays == Integer.MIN_VALUE) {
+            return "";
+        }
+        if (fromDate != null && toDate != null) {
+            return FLAG_VERSION_DATE + toDate + VALUE_FROMDATE + fromDate;
+        } else if (toDate != null && numDays != Integer.MIN_VALUE) {
+            try {
+                return FLAG_VERSION_DATE + toDate + VALUE_FROMDATE
+                        + calcDate(toDate, numDays);
+            } catch (ParseException ex) {
+                String msg = "Error parsing date: " + toDate;
+                throw new BuildException(msg, getLocation());
+            }
+        } else if (fromDate != null && numDays != Integer.MIN_VALUE) {
+            try {
+                return FLAG_VERSION_DATE + calcDate(fromDate, numDays)
+                        + VALUE_FROMDATE + fromDate;
+            } catch (ParseException ex) {
+                String msg = "Error parsing date: " + fromDate;
+                throw new BuildException(msg, getLocation());
+            }
+        } else {
+            return fromDate != null ? FLAG_VERSION + VALUE_FROMDATE
+                    + fromDate : FLAG_VERSION_DATE + toDate;
+        }
+    }
+
+    /**
+     * Builds and returns the -G- flag if required.
+     * @return An empty string if get local copy is true.
+     */
+    protected String getGetLocalCopy() {
+        return (!getLocalCopy) ? FLAG_NO_GET : "";
+    }
+
+    /**
+     * Gets the value of the fail on error flag.
+     * @return    True if the FailOnError flag has been set or if 'writablefiles=skip'.
+     */
+    private boolean getFailOnError() {
+        return getWritableFiles().equals(WRITABLE_SKIP) ? false : failOnError;
+    }
+
+
+    /**
+     * Gets the value set for the FileTimeStamp.
+     * if it equals "current" then we return -GTC
+     * if it equals "modified" then we return -GTM
+     * if it equals "updated" then we return -GTU
+     * otherwise we return -GTC
+     *
+     * @return The default file time flag, if not set.
+     */
+    public String getFileTimeStamp() {
+        if (timestamp == null) {
+            return "";
+        } else if (timestamp.getValue().equals(TIME_MODIFIED)) {
+            return FLAG_FILETIME_MODIFIED;
+        } else if (timestamp.getValue().equals(TIME_UPDATED)) {
+            return FLAG_FILETIME_UPDATED;
+        } else {
+            return FLAG_FILETIME_DEF;
+        }
+    }
+
+
+    /**
+     * Gets the value to determine the behaviour when encountering writable files.
+     * @return An empty String, if not set.
+     */
+    public String getWritableFiles() {
+        if (writableFiles == null) {
+            return "";
+        } else if (writableFiles.getValue().equals(WRITABLE_REPLACE)) {
+            return FLAG_REPLACE_WRITABLE;
+        } else if (writableFiles.getValue().equals(WRITABLE_SKIP)) {
+            // ss.exe exits with '100', when files have been skipped
+            // so we have to ignore the failure
+            failOnError = false;
+            return FLAG_SKIP_WRITABLE;
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     *  Sets up the required environment and executes the command line.
+     *
+     * @param  cmd  The command line to execute.
+     * @return      The return code from the exec'd process.
+     */
+    private int run(Commandline cmd) {
+        try {
+            Execute exe = new Execute(new LogStreamHandler(this,
+                    Project.MSG_INFO,
+                    Project.MSG_WARN));
+
+            // If location of ss.ini is specified we need to set the
+            // environment-variable SSDIR to this value
+            if (serverPath != null) {
+                String[] env = exe.getEnvironment();
+                if (env == null) {
+                    env = new String[0];
+                }
+                String[] newEnv = new String[env.length + 1];
+                for (int i = 0; i < env.length; i++) {
+                    newEnv[i] = env[i];
+                }
+                newEnv[env.length] = "SSDIR=" + serverPath;
+
+                exe.setEnvironment(newEnv);
+            }
+
+            exe.setAntRun(getProject());
+            exe.setWorkingDirectory(getProject().getBaseDir());
+            exe.setCommandline(cmd.getCommandline());
+            // Use the OS launcher so we get environment variables
+            exe.setVMLauncher(false);
+            return exe.execute();
+        } catch (IOException e) {
+            throw new BuildException(e, getLocation());
+        }
+    }
+
+     /**
+     * Calculates the start date for version comparison.
+     * <p>
+     * Calculates the date numDay days earlier than startdate.
+     * @param   startDate    The start date.
+     * @param   daysToAdd     The number of days to add.
+     * @return The calculated date.
+     * @throws ParseException
+     */
+    private String calcDate(String startDate, int daysToAdd) throws ParseException {
+        Date currentDate = new Date();
+        Calendar calendar = new GregorianCalendar();
+        currentDate = dateFormat.parse(startDate);
+        calendar.setTime(currentDate);
+        calendar.add(Calendar.DATE, daysToAdd);
+        return dateFormat.format(calendar.getTime());
+    }
+
+    /**
+     * Changes the password to '***' so it isn't displayed on screen if the build fails
+     *
+     * @param cmd   The command line to clean
+     * @return The command line as a string with out the password
+     */
+    private String formatCommandLine(Commandline cmd) {
+        StringBuffer sBuff = new StringBuffer(cmd.toString());
+        int indexUser = sBuff.substring(0).indexOf(FLAG_LOGIN);
+        if (indexUser > 0) {
+            int indexPass = sBuff.substring(0).indexOf(",", indexUser);
+            int indexAfterPass = sBuff.substring(0).indexOf(" ", indexPass);
+
+            for (int i = indexPass + 1; i < indexAfterPass; i++) {
+                sBuff.setCharAt(i, '*');
+            }
+        }
+        return sBuff.toString();
+    }
+
+    /**
+     * Extention of EnumeratedAttribute to hold the values for file time stamp.
+     */
+    public static class CurrentModUpdated extends EnumeratedAttribute {
+        /**
+         * Gets the list of allowable values.
+         * @return The values.
+         */
+        public String[] getValues() {
+            return new String[] {TIME_CURRENT, TIME_MODIFIED, TIME_UPDATED};
+        }
+    }
+
+    /**
+     * Extention of EnumeratedAttribute to hold the values for writable filess.
+     */
+    public static class WritableFiles extends EnumeratedAttribute {
+        /**
+         * Gets the list of allowable values.
+         * @return The values.
+         */
+        public String[] getValues() {
+            return new String[] {WRITABLE_REPLACE, WRITABLE_SKIP, WRITABLE_FAIL};
+        }
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSADD.java b/src/main/org/apache/ant/vss/MSVSSADD.java
new file mode 100644
index 0000000..e52095d
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSADD.java
@@ -0,0 +1,122 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Performs Add commands to Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vssadd" category="scm"
+ */
+public class MSVSSADD extends MSVSS {
+
+    private String localPath = null;
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    protected Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a localPath ...
+        if (getLocalpath() == null) {
+            String msg = "localPath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+
+        // build the command line from what we got the format is
+        // ss Add VSS items [-B] [-C] [-D-] [-H] [-I-] [-K] [-N] [-O] [-R] [-W] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_ADD);
+
+        // VSS items
+        commandLine.createArgument().setValue(getLocalpath());
+        // -I- or -I-Y or -I-N
+        commandLine.createArgument().setValue(getAutoresponse());
+        // -R
+        commandLine.createArgument().setValue(getRecursive());
+        // -W
+        commandLine.createArgument().setValue(getWritable());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+        // -C
+        commandLine.createArgument().setValue(getComment());
+
+        return commandLine;
+    }
+
+    /**
+     * Returns the local path without the flag.; required
+     * @todo See why this returns the local path without the flag.
+     * @return The local path value.
+     */
+    protected String getLocalpath() {
+        return localPath;
+    }
+
+    /**
+     * Add files recursively. Defaults to false.
+     *
+     * @param recursive  The boolean value for recursive.
+     */
+    public void setRecursive(boolean recursive) {
+        super.setInternalRecursive(recursive);
+    }
+
+    /**
+     * Unset the READ-ONLY flag on local copies of files added to VSS. Defaults to false.
+     *
+     * @param   writable The boolean value for writable.
+     */
+    public final void setWritable(boolean writable) {
+        super.setInternalWritable(writable);
+    }
+
+    /**
+     * Autoresponce behaviour. Valid options are Y and N.
+     *
+     * @param response The auto response value.
+     */
+    public void setAutoresponse(String response) {
+        super.setInternalAutoResponse(response);
+    }
+
+    /**
+     * Comment to apply to files added to SourceSafe.
+     *
+     * @param comment The comment to apply in SourceSafe
+     */
+    public void setComment(String comment) {
+        super.setInternalComment(comment);
+    }
+
+    /**
+     * Override the project working directory.
+     *
+     * @param   localPath   The path on disk.
+     */
+    public void setLocalpath(Path localPath) {
+        this.localPath = localPath.toString();
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSCHECKIN.java b/src/main/org/apache/ant/vss/MSVSSCHECKIN.java
new file mode 100644
index 0000000..4a3b4e9
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSCHECKIN.java
@@ -0,0 +1,114 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Performs CheckIn commands to Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vsscheckin" category="scm"
+ */
+public class MSVSSCHECKIN extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    protected Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir ...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+
+        // build the command line from what we got the format is
+        // ss Checkin VSS items [-H] [-C] [-I-] [-N] [-O] [-R] [-W] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_CHECKIN);
+
+        // VSS items
+        commandLine.createArgument().setValue(getVsspath());
+        // -GL
+        commandLine.createArgument().setValue(getLocalpath());
+        // -I- or -I-Y or -I-N
+        commandLine.createArgument().setValue(getAutoresponse());
+        // -R
+        commandLine.createArgument().setValue(getRecursive());
+        // -W
+        commandLine.createArgument().setValue(getWritable());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+        // -C
+        commandLine.createArgument().setValue(getComment());
+
+        return commandLine;
+    }
+
+    /**
+     * Override the project working directory.
+     *
+     * @param   localPath   The path on disk.
+     */
+    public void setLocalpath(Path localPath) {
+        super.setInternalLocalPath(localPath.toString());
+    }
+
+    /**
+     * Check-in files recursively. Defaults to false.
+     *
+     * @param recursive  The boolean value for recursive.
+     */
+    public void setRecursive(boolean recursive) {
+        super.setInternalRecursive(recursive);
+    }
+
+    /**
+     * Unset the READ-ONLY flag on local copies of files checked-in to VSS.
+     * Defaults to false.
+     *
+     * @param   writable The boolean value for writable.
+     */
+    public final void setWritable(boolean writable) {
+        super.setInternalWritable(writable);
+    }
+
+    /**
+     * Autoresponce behaviour. Valid options are Y and N.
+     *
+     * @param response The auto response value.
+     */
+    public void setAutoresponse(String response) {
+        super.setInternalAutoResponse(response);
+    }
+
+    /**
+     * Comment to apply to files checked-in to SourceSafe.
+     *
+     * @param comment The comment to apply in SourceSafe
+     */
+    public void setComment(String comment) {
+        super.setInternalComment(comment);
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSCHECKOUT.java b/src/main/org/apache/ant/vss/MSVSSCHECKOUT.java
new file mode 100644
index 0000000..b0506eb
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSCHECKOUT.java
@@ -0,0 +1,165 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Performs CheckOut commands to Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vsscheckout" category="scm"
+ * @ant.attribute.group name="vdl" description="Only one of version, date or label"
+ */
+public class MSVSSCHECKOUT extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    protected Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir ...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+
+        // build the command line from what we got the format is
+        // ss Checkout VSS items [-G] [-C] [-H] [-I-] [-N] [-O] [-R] [-V] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_CHECKOUT);
+
+        // VSS items
+        commandLine.createArgument().setValue(getVsspath());
+        // -GL
+        commandLine.createArgument().setValue(getLocalpath());
+        // -I- or -I-Y or -I-N
+        commandLine.createArgument().setValue(getAutoresponse());
+        // -R
+        commandLine.createArgument().setValue(getRecursive());
+        // -V
+        commandLine.createArgument().setValue(getVersionDateLabel());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+        // -G
+        commandLine.createArgument().setValue(getFileTimeStamp());
+        // -GWS or -GWR
+        commandLine.createArgument().setValue(getWritableFiles());
+        // -G-
+        commandLine.createArgument().setValue(getGetLocalCopy());
+
+        return commandLine;
+    }
+
+    /**
+     * Override the project working directory.
+     *
+     * @param   localPath   The path on disk.
+     */
+    public void setLocalpath(Path localPath) {
+        super.setInternalLocalPath(localPath.toString());
+    }
+
+    /**
+     * Check-out files recursively. Defaults to false.
+     *
+     * @param recursive  The boolean value for recursive.
+     */
+    public void setRecursive(boolean recursive) {
+        super.setInternalRecursive(recursive);
+    }
+
+    /**
+     * Version to check-out.
+     *
+     * @param  version The version to check-out.
+     *
+     * @ant.attribute group="vdl"
+     */
+    public void setVersion(String version) {
+        super.setInternalVersion(version);
+    }
+
+    /**
+     * Date to check-out.
+     *
+     * @param  date The date to check-out.
+     *
+     * @ant.attribute group="vdl"
+     */
+    public void setDate(String date) {
+        super.setInternalDate(date);
+    }
+
+    /**
+     * Label to check-out.
+     *
+     * @param  label The label to check-out.
+     *
+     * @ant.attribute group="vdl"
+     */
+    public void setLabel(String label) {
+        super.setInternalLabel(label);
+    }
+
+    /**
+     * Autoresponce behaviour. Valid options are Y and N.
+     *
+     * @param response The auto response value.
+     */
+    public void setAutoresponse(String response) {
+        super.setInternalAutoResponse(response);
+    }
+
+    /**
+     * Date and time stamp given to the local copy. Defaults to <code>current</code>.
+     *
+     * @param timestamp     The file time stamping behaviour.
+     */
+    public void setFileTimeStamp(CurrentModUpdated timestamp) {
+        super.setInternalFileTimeStamp(timestamp);
+    }
+
+    /**
+     * Action taken when local files are writable. Defaults to <code>fail</code>.
+     * <p>
+     * Due to ss.exe returning with an exit code of '100' for both errors and when
+     * a file has been skipped, <code>failonerror</code> is set to false when using
+     * the <code>skip</code> option.
+     * </p>
+     *
+     * @param files     The writable files behaviour
+     */
+    public void setWritableFiles(WritableFiles files) {
+        super.setInternalWritableFiles(files);
+    }
+
+    /**
+     * Retrieve a local copy during a checkout. Defaults to true.
+     *
+     * @param get   The get local copy behaviour
+     */
+    public void setGetLocalCopy(boolean get) {
+        super.setInternalGetLocalCopy(get);
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSCLOAK.java b/src/main/org/apache/ant/vss/MSVSSCLOAK.java
new file mode 100644
index 0000000..a423dc8
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSCLOAK.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+public class MSVSSCLOAK extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+        // Cloak always returns 1 - must set failonerror="false" as workaround
+        this.setFailOnError(false);
+        // build the command line from what we got
+        // the format is:
+        // ss Cloak VSS project path
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_CLOAK);
+
+        // VSS items (from)
+        commandLine.createArgument().setValue(getVsspath());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+
+        return commandLine;
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSCP.java b/src/main/org/apache/ant/vss/MSVSSCP.java
new file mode 100644
index 0000000..b839b7d
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSCP.java
@@ -0,0 +1,69 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Performs CP (Change Project) commands to Microsoft Visual SourceSafe.
+ * <p>This task is typically used before a VssAdd in order to set the target project</p>
+ *
+ * @ant.task name="vsscp" category="scm"
+ */
+public class MSVSSCP extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    protected Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir ...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+
+        // build the command line from what we got the format is
+        // ss CP VSS items [-H] [-I-] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_CP);
+
+        // VSS items
+        commandLine.createArgument().setValue(getVsspath());
+        // -I- or -I-Y or -I-N
+        commandLine.createArgument().setValue(getAutoresponse());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+
+        return commandLine;
+    }
+
+    /**
+     * Autoresponce behaviour. Valid options are Y and N.
+     *
+     * @param response The auto response value.
+     */
+    public void setAutoresponse(String response) {
+        super.setInternalAutoResponse(response);
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSCREATE.java b/src/main/org/apache/ant/vss/MSVSSCREATE.java
new file mode 100644
index 0000000..9bf8899
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSCREATE.java
@@ -0,0 +1,91 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Creates a new project in Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vsscreate" category="scm"
+ */
+public class MSVSSCREATE extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+
+        // build the command line from what we got
+        // the format is:
+        // ss Create VSS items [-C] [-H] [-I-] [-N] [-O] [-S] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_CREATE);
+
+        // VSS items
+        commandLine.createArgument().setValue(getVsspath());
+        // -C
+        commandLine.createArgument().setValue(getComment());
+        // -I- or -I-Y or -I-N
+        commandLine.createArgument().setValue(getAutoresponse());
+        // -O-
+        commandLine.createArgument().setValue(getQuiet());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+
+        return commandLine;
+    }
+
+    /**
+     * Comment to apply to the project created in SourceSafe.
+     *
+     * @param comment The comment to apply in SourceSafe
+     */
+    public void setComment(String comment) {
+        super.setInternalComment(comment);
+    }
+
+    /**
+     * Enable quiet mode. Defaults to false.
+     *
+     * @param   quiet The boolean value for quiet.
+     */
+    public final void setQuiet (boolean quiet) {
+        super.setInternalQuiet(quiet);
+    }
+
+    /**
+     * Autoresponce behaviour. Valid options are Y and N.
+     *
+     * @param response The auto response value.
+     */
+    public void setAutoresponse(String response) {
+        super.setInternalAutoResponse(response);
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSConstants.java b/src/main/org/apache/ant/vss/MSVSSConstants.java
new file mode 100644
index 0000000..1b5486b
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSConstants.java
@@ -0,0 +1,114 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.vss;
+
+/**
+ *  Holds all the constants for the VSS tasks.
+ *
+ */
+public interface MSVSSConstants {
+    /**  Constant for the thing to execute  */
+    String SS_EXE = "ss";
+    /** Dollar Sigh to prefix the project path */
+    String PROJECT_PREFIX = "$";
+
+    /**  The 'CP' command  */
+    String COMMAND_CP = "CP";
+    /**  The 'Add' command  */
+    String COMMAND_ADD = "Add";
+    /**  The 'Get' command  */
+    String COMMAND_GET = "Get";
+    /**  The 'Checkout' command  */
+    String COMMAND_CHECKOUT = "Checkout";
+    /**  The 'Checkin' command  */
+    String COMMAND_CHECKIN = "Checkin";
+    /**  The 'Label' command  */
+    String COMMAND_LABEL = "Label";
+    /**  The 'History' command  */
+    String COMMAND_HISTORY = "History";
+    /**  The 'Create' command  */
+    String COMMAND_CREATE = "Create";
+    /**  The 'Destroy' command  */
+    String COMMAND_DESTROY = "Destroy";
+    /**  The 'Delete' command  */
+    String COMMAND_DELETE = "Delete";
+    /**  The 'Recover' command  */
+    String COMMAND_RECOVER = "Recover";
+    /**  The 'Move' command  */
+    String COMMAND_MOVE = "Move";
+    /**  The 'Cloak' command  */
+    String COMMAND_CLOAK = "Cloak";
+    /**  The 'Decloak' command  */
+    String COMMAND_DECLOAK = "Decloak";
+    /**  The 'Locate' command  */
+    String COMMAND_LOCATE = "Locate";
+    /**  The 'Status' command  */
+    String COMMAND_STATUS = "Status";
+    
+    /**  The brief style flag  */
+    String STYLE_BRIEF = "brief";
+    /**  The codediff style flag  */
+    String STYLE_CODEDIFF = "codediff";
+    /**  The nofile style flag  */
+    String STYLE_NOFILE = "nofile";
+    /**  The default style flag  */
+    String STYLE_DEFAULT = "default";
+
+    /**  The text for  current (default) timestamp */
+    String TIME_CURRENT = "current";
+    /**  The text for  modified timestamp */
+    String TIME_MODIFIED = "modified";
+    /**  The text for  updated timestamp */
+    String TIME_UPDATED = "updated";
+
+    /**  The text for replacing writable files   */
+    String WRITABLE_REPLACE = "replace";
+    /**  The text for skiping writable files  */
+    String WRITABLE_SKIP = "skip";
+    /**  The text for failing on writable files  */
+    String WRITABLE_FAIL = "fail";
+
+    String FLAG_LOGIN = "-Y";
+    String FLAG_OVERRIDE_WORKING_DIR = "-GL";
+    String FLAG_AUTORESPONSE_DEF = "-I-";
+    String FLAG_AUTORESPONSE_YES = "-I-Y";
+    String FLAG_AUTORESPONSE_NO = "-I-N";
+    String FLAG_RECURSION = "-R";
+    String FLAG_VERSION = "-V";
+    String FLAG_VERSION_DATE = "-Vd";
+    String FLAG_VERSION_LABEL = "-VL";
+    String FLAG_WRITABLE = "-W";
+    String VALUE_NO = "-N";
+    String VALUE_YES = "-Y";
+    String FLAG_QUIET = "-O-";
+    String FLAG_COMMENT = "-C";
+    String FLAG_LABEL = "-L";
+    String VALUE_FROMDATE = "~d";
+    String VALUE_FROMLABEL = "~L";
+    String FLAG_OUTPUT = "-O";
+    String FLAG_USER = "-U";
+    String FLAG_NO_FILE = "-F-";
+    String FLAG_BRIEF = "-B";
+    String FLAG_CODEDIFF = "-D";
+    String FLAG_FILETIME_DEF = "-GTC";
+    String FLAG_FILETIME_MODIFIED = "-GTM";
+    String FLAG_FILETIME_UPDATED = "-GTU";
+    String FLAG_REPLACE_WRITABLE = "-GWR";
+    String FLAG_SKIP_WRITABLE = "-GWS";
+    String FLAG_NO_GET = "-G-";
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSDECLOAK.java b/src/main/org/apache/ant/vss/MSVSSDECLOAK.java
new file mode 100644
index 0000000..a2bb932
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSDECLOAK.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+public class MSVSSDECLOAK extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+        // Decloak always returns 1 - must set failonerror="false" as workaround
+        this.setFailOnError(false);
+        // build the command line from what we got
+        // the format is:
+        // ss Decloak VSS project path
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_DECLOAK);
+
+        // VSS items (from)
+        commandLine.createArgument().setValue(getVsspath());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+
+        return commandLine;
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSDELETE.java b/src/main/org/apache/ant/vss/MSVSSDELETE.java
new file mode 100644
index 0000000..c95b078
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSDELETE.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+public class MSVSSDELETE extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+        // build the command line from what we got
+        // the format is:
+        // ss Delete VSS items [-H] [-I-] [-N] [-O] [-S] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_DELETE);
+
+        // VSS items (from)
+        commandLine.createArgument().setValue(getVsspath());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+        // -I-
+        commandLine.createArgument().setValue(getAutoresponse());
+        
+        return commandLine;
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSDESTROY.java b/src/main/org/apache/ant/vss/MSVSSDESTROY.java
new file mode 100644
index 0000000..37fc597
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSDESTROY.java
@@ -0,0 +1,80 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Permanently removes a file or project from Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vssdestroy" category="scm"
+ */
+public class MSVSSDESTROY extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+
+        // build the command line from what we got
+        // the format is:
+        // ss Destroy VSS items [-H] [-I-] [-N] [-O] [-S] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_DESTROY);
+
+        // VSS items
+        commandLine.createArgument().setValue(getVsspath());
+        // -I- or -I-Y or -I-N
+        commandLine.createArgument().setValue(getAutoresponse());
+        // -O-
+        commandLine.createArgument().setValue(getQuiet());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+
+        return commandLine;
+    }
+    
+    /**
+     * Enable quiet mode. Defaults to false.
+     *
+     * @param   quiet The boolean value for quiet.
+     */
+    public final void setQuiet (boolean quiet) {
+        super.setInternalQuiet(quiet);
+    }
+
+    /**
+     * Autoresponce behaviour. Valid options are Y and N.
+     *
+     * @param response The auto response value.
+     */
+    public void setAutoresponse(String response) {
+        super.setInternalAutoResponse(response);
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSGET.java b/src/main/org/apache/ant/vss/MSVSSGET.java
new file mode 100644
index 0000000..0eb5160
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSGET.java
@@ -0,0 +1,172 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Perform Get commands from Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vssget" category="scm"
+ * @ant.attribute.group name="vdl" description="Only one of version, date or label"
+ */
+public class MSVSSGET extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // build the command line from what we got the format is
+        // ss Get VSS items [-G] [-H] [-I-] [-N] [-O] [-R] [-V] [-W] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_GET);
+
+        if (getVsspath() == null) {
+            throw new BuildException("vsspath attribute must be set!", getLocation());
+        }
+        commandLine.createArgument().setValue(getVsspath());
+
+        // -GL
+        commandLine.createArgument().setValue(getLocalpath());
+        // -I- or -I-Y or -I-N
+        commandLine.createArgument().setValue(getAutoresponse());
+        // -O-
+        commandLine.createArgument().setValue(getQuiet());
+        // -R
+        commandLine.createArgument().setValue(getRecursive());
+        // -V
+        commandLine.createArgument().setValue(getVersionDateLabel());
+        // -W
+        commandLine.createArgument().setValue(getWritable());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+        // -G
+        commandLine.createArgument().setValue(getFileTimeStamp());
+        // -GWS or -GWR
+        commandLine.createArgument().setValue(getWritableFiles());
+
+        return commandLine;
+    }
+
+    /**
+     * Override the project working directory.
+     *
+     * @param   localPath   The path on disk.
+     */
+    public void setLocalpath(Path localPath) {
+        super.setInternalLocalPath(localPath.toString());
+    }
+
+    /**
+     * Get files recursively. Defaults to false.
+     *
+     * @param recursive  The boolean value for recursive.
+     */
+    public final void setRecursive(boolean recursive) {
+        super.setInternalRecursive(recursive);
+    }
+
+    /**
+     * Enable quiet mode. Defaults to false.
+     *
+     * @param   quiet The boolean value for quiet.
+     */
+    public final void setQuiet (boolean quiet) {
+        super.setInternalQuiet(quiet);
+    }
+
+    /**
+     * Unset the READ-ONLY flag on files retrieved from VSS. Defaults to false.
+     *
+     * @param   writable The boolean value for writable.
+     */
+    public final void setWritable(boolean writable) {
+        super.setInternalWritable(writable);
+    }
+
+    /**
+     * Version to get.
+     *
+     * @param  version The version to get.
+     *
+     * @ant.attribute group="vdl"
+     */
+    public void setVersion(String version) {
+        super.setInternalVersion(version);
+    }
+
+    /**
+     * Date to get.
+     *
+     * @param  date The date to get.
+     *
+     * @ant.attribute group="vdl"
+     */
+    public void setDate(String date) {
+        super.setInternalDate(date);
+    }
+
+    /**
+     * Label to get.
+     *
+     * @param  label The label to get.
+     *
+     * @ant.attribute group="vdl"
+     */
+    public void setLabel(String label) {
+        super.setInternalLabel(label);
+    }
+
+    /**
+     * Autoresponce behaviour. Valid options are Y and N.
+     *
+     * @param response The auto response value.
+     */
+    public void setAutoresponse(String response) {
+        super.setInternalAutoResponse(response);
+    }
+
+    /**
+     * Date and time stamp given to the local copy. Defaults to <code>current</code>.
+     *
+     * @param timestamp     The file time stamping behaviour.
+     */
+    public void setFileTimeStamp(CurrentModUpdated timestamp) {
+        super.setInternalFileTimeStamp(timestamp);
+    }
+
+    /**
+     * Action taken when local files are writable. Defaults to <code>fail</code>.
+     * <p>
+     * Due to ss.exe returning with an exit code of '100' for both errors and when
+     * a file has been skipped, <code>failonerror</code> is set to false when using
+     * the <code>skip</code> option.
+     *
+     * @param files The action to take.
+     */
+    public void setWritableFiles(WritableFiles files) {
+        super.setInternalWritableFiles(files);
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSHISTORY.java b/src/main/org/apache/ant/vss/MSVSSHISTORY.java
new file mode 100644
index 0000000..3d5719d
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSHISTORY.java
@@ -0,0 +1,199 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Performs History commands to Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vsshistory" category="scm"
+ */
+public class MSVSSHISTORY extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir and a label ...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+
+        // build the command line from what we got the format is
+        // ss History elements [-H] [-L] [-N] [-O] [-V] [-Y] [-#] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_HISTORY);
+
+        // VSS items
+        commandLine.createArgument().setValue(getVsspath());
+        // -I-
+        commandLine.createArgument().setValue(getAutoresponse());
+        // -Vd
+        commandLine.createArgument().setValue(getVersionDate());
+        // -VL
+        commandLine.createArgument().setValue(getVersionLabel());
+        // -R
+        commandLine.createArgument().setValue(getRecursive());
+        // -B / -D / -F-
+        commandLine.createArgument().setValue(getStyle());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+        // -O
+        commandLine.createArgument().setValue(getOutput());
+
+        return commandLine;
+    }
+
+    /**
+     * Retrieve history recursively. Defaults to false.
+     *
+     * @param recursive  The boolean value for recursive.
+     */
+    public void setRecursive(boolean recursive) {
+        super.setInternalRecursive(recursive);
+    }
+
+    /**
+     * Name of the user whose change history is generated.
+     *
+     * @param   user The username.
+     */
+    public void setUser(String user) {
+        super.setInternalUser(user);
+    }
+
+    /**
+     * Date representing the 'start' of the range.
+     *
+     * @param   fromDate    The start date.
+     */
+    public void setFromDate(String fromDate) {
+        super.setInternalFromDate(fromDate);
+    }
+
+    /**
+     * Date representing the 'end' of the range.
+     *
+     * @param   toDate    The end date.
+     */
+    public void setToDate(String toDate) {
+        super.setInternalToDate(toDate);
+    }
+
+    /**
+     * Label representing the 'start' of the range.
+     *
+     * @param   fromLabel    The start label.
+     */
+    public void setFromLabel(String fromLabel) {
+        super.setInternalFromLabel(fromLabel);
+    }
+
+    /**
+     * Label representing the 'end' of the range.
+     *
+     * @param   toLabel    The end label.
+     */
+    public void setToLabel(String toLabel) {
+        super.setInternalToLabel(toLabel);
+    }
+
+    /**
+     * Number of days for comparison.
+     * Defaults to 2 days.
+     *
+     * @param   numd    The number of days.
+     */
+    public void setNumdays(int numd) {
+        super.setInternalNumDays(numd);
+    }
+
+    /**
+     * Output file name for the history.
+     *
+     * @param   outfile The output file name.
+     */
+    public void setOutput(File outfile) {
+        if (outfile != null) {
+            super.setInternalOutputFilename(outfile.getAbsolutePath());
+        }
+    }
+
+    /**
+     * Format of dates in <code>fromDate</code and <code>toDate</code>.
+     * Used when calculating dates with the numdays attribute.
+     * This string uses the formatting rules of <code>SimpleDateFormat</code>.
+     * Defaults to <code>DateFormat.SHORT</code>.
+     *
+     * @param   dateFormat  The date format.
+     */
+    public void setDateFormat(String dateFormat) {
+        super.setInternalDateFormat(new SimpleDateFormat(dateFormat));
+    }
+
+   /**
+     * Output style. Valid options are:
+     * <ul>
+     * <li>brief:    -B Display a brief history.
+     * <li>codediff: -D Display line-by-line file changes.
+     * <li>nofile:   -F- Do not display individual file updates in the project history.
+     * <li>default:  No option specified. Display in Source Safe's default format.
+     * </ul>
+     *
+     * @param attr The history style:
+     */
+    public void setStyle(BriefCodediffNofile attr) {
+        String option = attr.getValue();
+        if (option.equals(STYLE_BRIEF)) {
+            super.setInternalStyle(FLAG_BRIEF);
+        } else if (option.equals(STYLE_CODEDIFF)) {
+            super.setInternalStyle(FLAG_CODEDIFF);
+        } else if (option.equals(STYLE_DEFAULT)) {
+            super.setInternalStyle("");
+        } else if (option.equals(STYLE_NOFILE)) {
+            super.setInternalStyle(FLAG_NO_FILE);
+        } else {
+            throw new BuildException("Style " + attr + " unknown.", getLocation());
+        }
+    }
+
+    /**
+     * Extention of EnumeratedAttribute to hold the values for style.
+     */
+    public static class BriefCodediffNofile extends EnumeratedAttribute {
+        /**
+         * Gets the list of allowable values.
+         * @return The values.
+         */
+        public String[] getValues() {
+            return new String[] {STYLE_BRIEF, STYLE_CODEDIFF, STYLE_NOFILE, STYLE_DEFAULT};
+        }
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSLABEL.java b/src/main/org/apache/ant/vss/MSVSSLABEL.java
new file mode 100644
index 0000000..ecbfaf0
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSLABEL.java
@@ -0,0 +1,108 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Performs Label commands to Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vsslabel" category="scm"
+ */
+public class MSVSSLABEL extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir and a label ...
+        if (getVsspath() == null) {
+            throw new BuildException("vsspath attribute must be set!", getLocation());
+        }
+
+        String label = getLabel();
+        if (label.equals("")) {
+            String msg = "label attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+
+        // build the command line from what we got the format is
+        // ss Label VSS items [-C] [-H] [-I-] [-Llabel] [-N] [-O] [-V] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_LABEL);
+
+        // VSS items
+        commandLine.createArgument().setValue(getVsspath());
+        // -C
+        commandLine.createArgument().setValue(getComment());
+        // -I- or -I-Y or -I-N
+        commandLine.createArgument().setValue(getAutoresponse());
+        // -L Specify the new label on the command line (instead of being prompted)
+        commandLine.createArgument().setValue(label);
+        // -V Label an existing file or project version
+        commandLine.createArgument().setValue(getVersion());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+
+        return commandLine;
+    }
+
+    /**
+     * Label to apply in SourceSafe.
+     *
+     * @param  label The label to apply.
+     *
+     * @ant.attribute group="required"
+     */
+    public void setLabel(String label) {
+        super.setInternalLabel(label);
+    }
+
+    /**
+     * Version to label.
+     *
+     * @param  version The version to label.
+     */
+    public void setVersion(String version) {
+        super.setInternalVersion(version);
+    }
+
+    /**
+     * Comment to apply to files labeled in SourceSafe.
+     *
+     * @param comment The comment to apply in SourceSafe
+     */
+    public void setComment(String comment) {
+        super.setInternalComment(comment);
+    }
+
+    /**
+     * Autoresponce behaviour. Valid options are Y and N.
+     *
+     * @param response The auto response value.
+     */
+    public void setAutoresponse(String response) {
+        super.setInternalAutoResponse(response);
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSLOCATE.java b/src/main/org/apache/ant/vss/MSVSSLOCATE.java
new file mode 100644
index 0000000..580a020
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSLOCATE.java
@@ -0,0 +1,55 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+public class MSVSSLOCATE extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+        // Locate always returns 1 - must set failonerror="false" as workaround
+        this.setFailOnError(false);
+        // build the command line from what we got
+        // the format is:
+        // ss Locate filename [-H] [-I-] [-N] [-O] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_LOCATE);
+
+        // VSS items (from)
+        commandLine.createArgument().setValue(getVsspath());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+        // -I-
+        commandLine.createArgument().setValue(getAutoresponse());
+        return commandLine;
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSMOVE.java b/src/main/org/apache/ant/vss/MSVSSMOVE.java
new file mode 100644
index 0000000..8fcb042
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSMOVE.java
@@ -0,0 +1,72 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+public class MSVSSMOVE extends MSVSS {
+
+    private String destination;
+    
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+
+        // build the command line from what we got
+        // the format is:
+        // ss Destroy VSS items [-H] [-I-] [-N] [-O] [-S] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_MOVE);
+
+        // VSS items (from)
+        commandLine.createArgument().setValue(getVsspath());
+        // VSS item (to)
+        commandLine.createArgument().setValue(destination);
+        // -I- or -I-Y or -I-N
+        commandLine.createArgument().setValue(getAutoresponse());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+
+        return commandLine;
+    }
+    
+    /**
+     * Autoresponce behaviour. Valid options are Y and N.
+     *
+     * @param response The auto response value.
+     */
+    public void setAutoresponse(String response) {
+        super.setInternalAutoResponse(response);
+    }
+    
+    public void setDestination(String d) {
+        this.destination = d;
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSRECOVER.java b/src/main/org/apache/ant/vss/MSVSSRECOVER.java
new file mode 100644
index 0000000..437870b
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSRECOVER.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+public class MSVSSRECOVER extends MSVSS {
+
+    /**
+     * Builds a command line to execute ss.
+     * @return     The constructed commandline.
+     */
+    Commandline buildCmdLine() {
+        Commandline commandLine = new Commandline();
+
+        // first off, make sure that we've got a command and a vssdir...
+        if (getVsspath() == null) {
+            String msg = "vsspath attribute must be set!";
+            throw new BuildException(msg, getLocation());
+        }
+        // build the command line from what we got
+        // the format is:
+        // ss Recover VSS items [-G] [-H] [-I-] [-N] [-O] [-S] [-W] [-Y] [-?]
+        // as specified in the SS.EXE help
+        commandLine.setExecutable(getSSCommand());
+        commandLine.createArgument().setValue(COMMAND_RECOVER);
+
+        // VSS items (from)
+        commandLine.createArgument().setValue(getVsspath());
+        // -Y
+        commandLine.createArgument().setValue(getLogin());
+        // -I-
+        commandLine.createArgument().setValue(getAutoresponse());
+        //-GWS or -GWR
+        commandLine.createArgument().setValue(getWritableFiles());
+        return commandLine;
+    }
+}
diff --git a/src/main/org/apache/ant/vss/MSVSSSTATUS.java b/src/main/org/apache/ant/vss/MSVSSSTATUS.java
new file mode 100644
index 0000000..320753a
--- /dev/null
+++ b/src/main/org/apache/ant/vss/MSVSSSTATUS.java
@@ -0,0 +1,58 @@
+/*

+ *  Licensed to the Apache Software Foundation (ASF) under one or more

+ *  contributor license agreements.  See the NOTICE file distributed with

+ *  this work for additional information regarding copyright ownership.

+ *  The ASF licenses this file to You under the Apache License, Version 2.0

+ *  (the "License"); you may not use this file except in compliance with

+ *  the License.  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ *

+ */

+package org.apache.ant.vss;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.types.Commandline;

+

+public class MSVSSSTATUS extends MSVSS {

+    

+    /**

+     * Builds a command line to execute ss.

+     * @return     The constructed commandline.

+     */

+    Commandline buildCmdLine() {

+        Commandline commandLine = new Commandline();

+

+        // first off, make sure that we've got a command and a vssdir...

+        if (getVsspath() == null) {

+            String msg = "vsspath attribute must be set!";

+            throw new BuildException(msg, getLocation());

+        }

+        // build the command line from what we got

+        // the format is:

+        // ss Status [VSS items] [-H] [-I-] [-N] [-O] [-P[project]] [-R] [-U[username]] [-Y] [-?]

+        // as specified in the SS.EXE help

+        commandLine.setExecutable(getSSCommand());

+        commandLine.createArgument().setValue(COMMAND_STATUS);

+

+        // VSS items (from)

+        commandLine.createArgument().setValue(getVsspath());

+        // -Y

+        commandLine.createArgument().setValue(getLogin());

+        // -I-

+        commandLine.createArgument().setValue(getAutoresponse());

+        // -U

+        commandLine.createArgument().setValue(getUser());

+        return commandLine;

+    }

+    

+    public void setUser(String u) {

+        super.setInternalUser(u);

+    }

+}

diff --git a/src/main/org/apache/ant/vss/antlib.xml b/src/main/org/apache/ant/vss/antlib.xml
new file mode 100644
index 0000000..494c44a
--- /dev/null
+++ b/src/main/org/apache/ant/vss/antlib.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<antlib>
+  <taskdef
+    name="vss"
+    classname="org.apache.ant.vss.MSVSS"
+    />
+  <taskdef
+    name="add"
+    classname="org.apache.ant.vss.MSVSSADD"
+    />
+  <taskdef
+    name="checkin"
+    classname="org.apache.ant.vss.MSVSSCHECKIN"
+    />
+  <taskdef
+    name="checkout"
+    classname="org.apache.ant.vss.MSVSSCHECKOUT"
+    />
+  <taskdef
+    name="cp"
+    classname="org.apache.ant.vss.MSVSSCP"
+    />
+  <taskdef
+    name="create"
+    classname="org.apache.ant.vss.MSVSSCREATE"
+    />
+  <taskdef
+    name="get"
+    classname="org.apache.ant.vss.MSVSSGET"
+    />
+  <taskdef
+    name="history"
+    classname="org.apache.ant.vss.MSVSSHISTORY"
+    />
+  <taskdef
+    name="label"
+    classname="org.apache.ant.vss.MSVSSLABEL"
+    />
+  <taskdef
+    name="destroy"
+    classname="org.apache.ant.vss.MSVSSDESTROY"
+    />
+  <taskdef
+    name="delete"
+    classname="org.apache.ant.vss.MSVSSDELETE"
+    />
+  <taskdef
+    name="recover"
+    classname="org.apache.ant.vss.MSVSSRECOVER"
+    />
+  <taskdef
+    name="move"
+    classname="org.apache.ant.vss.MSVSSMOVE"
+    />
+  <taskdef
+    name="cloak"
+    classname="org.apache.ant.vss.MSVSSCLOAK"
+    />
+  <taskdef
+    name="decloak"
+    classname="org.apache.ant.vss.MSVSSDECLOAK"
+    />
+  <taskdef
+    name="locate"
+    classname="org.apache.ant.vss.MSVSSLOCATE"
+    />
+  <taskdef
+    name="status"
+    classname="org.apache.ant.vss.MSVSSSTATUS"
+    />
+</antlib>
diff --git a/src/tests/junit/org/apache/ant/vss/MSVSSTest.java b/src/tests/junit/org/apache/ant/vss/MSVSSTest.java
new file mode 100644
index 0000000..225b517
--- /dev/null
+++ b/src/tests/junit/org/apache/ant/vss/MSVSSTest.java
@@ -0,0 +1,63 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.vss;
+
+import org.apache.tools.ant.BuildFileTest;
+
+public class MSVSSTest extends BuildFileTest {
+
+    public MSVSSTest() {
+        this("MSVSSTest");
+    }
+    
+    public MSVSSTest(String name) {
+        super(name);
+    }
+    
+    public void setUp() throws Exception {
+        configureProject("src/etc/testcases/msvss.xml");
+    }
+
+    public void tearDown() throws Exception {
+        executeTarget("cleanup");
+    }
+    
+    public void testMSVSS() throws Exception {
+        executeTarget("test-all");
+    }
+    
+    public void testMSVSSMOVE() throws Exception {
+        executeTarget("test-move");
+    }
+    
+    public void testMSVSSCLOAK() throws Exception {
+        executeTarget("test-cloak");
+    }
+    
+    public void testMSVSSDELETE() throws Exception {
+        executeTarget("test-delete");
+    }
+    
+    public void testMSVSSLOCATE() throws Exception {
+        executeTarget("test-locate");
+    }
+    
+    public void testMSVSSSTATUS() throws Exception {
+        executeTarget("test-status");
+    }
+}