Index: pom.xml
===================================================================
--- pom.xml	(revision 659128)
+++ pom.xml	(working copy)
@@ -164,7 +164,8 @@
     <module>continuum-test</module>
     <module>continuum-webapp</module>
     <module>continuum-xmlrpc</module>
-    <module>continuum-release</module>
+    <!-- module>continuum-release</module -->
+    <module>continuum-release2</module>
     <module>continuum-data-management</module>
     <module>continuum-configuration</module>
     <module>maven-continuum-plugin</module>
@@ -548,6 +549,11 @@
         <version>${pom.version}</version>
       </dependency>
       <dependency>
+        <groupId>org.apache.continuum</groupId>
+        <artifactId>continuum-release2</artifactId>
+        <version>${pom.version}</version>
+      </dependency>
+      <dependency>
         <groupId>net.sf.ehcache</groupId>
         <artifactId>ehcache</artifactId>
         <version>1.3.0</version>
Index: continuum-release2/.classpath
===================================================================
--- continuum-release2/.classpath	(revision 0)
+++ continuum-release2/.classpath	(revision 0)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry including="**/*.java" kind="src" output="target/test-classes" path="src/test/java"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/test/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
Index: continuum-release2/.project
===================================================================
--- continuum-release2/.project	(revision 0)
+++ continuum-release2/.project	(revision 0)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>continuum-release2</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.devzuz.q.maven.jdt.core.mavenIncrementalBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+		<nature>org.devzuz.q.maven.jdt.core.mavenNature</nature>
+	</natures>
+</projectDescription>
Index: continuum-release2/src/test/scm_save/hooks/pre-revprop-change.tmpl
===================================================================
--- continuum-release2/src/test/scm_save/hooks/pre-revprop-change.tmpl	(revision 0)
+++ continuum-release2/src/test/scm_save/hooks/pre-revprop-change.tmpl	(revision 0)
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+# PRE-REVPROP-CHANGE HOOK
+#
+# The pre-revprop-change hook is invoked before a revision property
+# is added, modified or deleted.  Subversion runs this hook by invoking
+# a program (script, executable, binary, etc.) named 'pre-revprop-change'
+# (for which this file is a template), with the following ordered
+# arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] REVISION     (the revision being tweaked)
+#   [3] USER         (the username of the person tweaking the property)
+#   [4] PROPNAME     (the property being set on the revision)
+#   [5] ACTION       (the property is being 'A'dded, 'M'odified, or 'D'eleted)
+#
+#   [STDIN] PROPVAL  ** the new property value is passed via STDIN.
+#
+# If the hook program exits with success, the propchange happens; but
+# if it exits with failure (non-zero), the propchange doesn't happen.
+# The hook program can use the 'svnlook' utility to examine the 
+# existing value of the revision property.
+#
+# WARNING: unlike other hooks, this hook MUST exist for revision
+# properties to be changed.  If the hook does not exist, Subversion 
+# will behave as if the hook were present, but failed.  The reason
+# for this is that revision properties are UNVERSIONED, meaning that
+# a successful propchange is destructive;  the old value is gone
+# forever.  We recommend the hook back up the old value somewhere.
+#
+# On a Unix system, the normal procedure is to have 'pre-revprop-change'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'pre-revprop-change' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'pre-revprop-change.bat' or 'pre-revprop-change.exe',
+# but the basic idea is the same.
+#
+# The hook program typically does not inherit the environment of
+# its parent process.  For example, a common problem is for the
+# PATH environment variable to not be set to its usual value, so
+# that subprograms fail to launch unless invoked via absolute path.
+# If you're having unexpected problems with a hook program, the
+# culprit may be unusual (or missing) environment variables.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter.
+# For more examples and pre-written hooks, see those in
+# the Subversion repository at
+# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
+# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
+
+
+REPOS="$1"
+REV="$2"
+USER="$3"
+PROPNAME="$4"
+ACTION="$5"
+
+if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi
+
+echo "Changing revision properties other than svn:log is prohibited" >&2
+exit 1
Index: continuum-release2/src/test/scm_save/hooks/post-commit.tmpl
===================================================================
--- continuum-release2/src/test/scm_save/hooks/post-commit.tmpl	(revision 0)
+++ continuum-release2/src/test/scm_save/hooks/post-commit.tmpl	(revision 0)
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+# POST-COMMIT HOOK
+#
+# The post-commit hook is invoked after a commit.  Subversion runs
+# this hook by invoking a program (script, executable, binary, etc.)
+# named 'post-commit' (for which this file is a template) with the 
+# following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] REV          (the number of the revision just committed)
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# Because the commit has already completed and cannot be undone,
+# the exit code of the hook program is ignored.  The hook program
+# can use the 'svnlook' utility to help it examine the
+# newly-committed tree.
+#
+# On a Unix system, the normal procedure is to have 'post-commit'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'post-commit' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'post-commit.bat' or 'post-commit.exe',
+# but the basic idea is the same.
+# 
+# The hook program typically does not inherit the environment of
+# its parent process.  For example, a common problem is for the
+# PATH environment variable to not be set to its usual value, so
+# that subprograms fail to launch unless invoked via absolute path.
+# If you're having unexpected problems with a hook program, the
+# culprit may be unusual (or missing) environment variables.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter.
+# For more examples and pre-written hooks, see those in
+# the Subversion repository at
+# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
+# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
+
+
+REPOS="$1"
+REV="$2"
+
+commit-email.pl "$REPOS" "$REV" commit-watchers@example.org
+log-commit.py --repository "$REPOS" --revision "$REV"
Index: continuum-release2/src/test/scm_save/hooks/post-lock.tmpl
===================================================================
--- continuum-release2/src/test/scm_save/hooks/post-lock.tmpl	(revision 0)
+++ continuum-release2/src/test/scm_save/hooks/post-lock.tmpl	(revision 0)
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# POST-LOCK HOOK
+#
+# The post-lock hook is run after a path is locked.  Subversion runs
+# this hook by invoking a program (script, executable, binary, etc.)
+# named 'post-lock' (for which this file is a template) with the 
+# following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] USER         (the user who created the lock)
+#
+# The paths that were just locked are passed to the hook via STDIN (as
+# of Subversion 1.2, only one path is passed per invocation, but the
+# plan is to pass all locked paths at once, so the hook program
+# should be written accordingly).
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# Because the lock has already been created and cannot be undone,
+# the exit code of the hook program is ignored.  The hook program
+# can use the 'svnlook' utility to help it examine the
+# newly-created lock.
+#
+# On a Unix system, the normal procedure is to have 'post-lock'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'post-lock' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'post-lock.bat' or 'post-lock.exe',
+# but the basic idea is the same.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter:
+
+REPOS="$1"
+USER="$2"
+
+# Send email to interested parties, let them know a lock was created:
+mailer.py lock "$REPOS" "$USER" /path/to/mailer.conf
Index: continuum-release2/src/test/scm_save/hooks/pre-commit.tmpl
===================================================================
--- continuum-release2/src/test/scm_save/hooks/pre-commit.tmpl	(revision 0)
+++ continuum-release2/src/test/scm_save/hooks/pre-commit.tmpl	(revision 0)
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+# PRE-COMMIT HOOK
+#
+# The pre-commit hook is invoked before a Subversion txn is
+# committed.  Subversion runs this hook by invoking a program
+# (script, executable, binary, etc.) named 'pre-commit' (for which
+# this file is a template), with the following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] TXN-NAME     (the name of the txn about to be committed)
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# If the hook program exits with success, the txn is committed; but
+# if it exits with failure (non-zero), the txn is aborted, no commit
+# takes place, and STDERR is returned to the client.   The hook
+# program can use the 'svnlook' utility to help it examine the txn.
+#
+# On a Unix system, the normal procedure is to have 'pre-commit'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+#   ***  NOTE: THE HOOK PROGRAM MUST NOT MODIFY THE TXN, EXCEPT  ***
+#   ***  FOR REVISION PROPERTIES (like svn:log or svn:author).   ***
+#
+#   This is why we recommend using the read-only 'svnlook' utility.
+#   In the future, Subversion may enforce the rule that pre-commit
+#   hooks should not modify the versioned data in txns, or else come
+#   up with a mechanism to make it safe to do so (by informing the
+#   committing client of the changes).  However, right now neither
+#   mechanism is implemented, so hook writers just have to be careful.
+#
+# Note that 'pre-commit' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'pre-commit.bat' or 'pre-commit.exe',
+# but the basic idea is the same.
+#
+# The hook program typically does not inherit the environment of
+# its parent process.  For example, a common problem is for the
+# PATH environment variable to not be set to its usual value, so
+# that subprograms fail to launch unless invoked via absolute path.
+# If you're having unexpected problems with a hook program, the
+# culprit may be unusual (or missing) environment variables.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter.
+# For more examples and pre-written hooks, see those in
+# the Subversion repository at
+# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
+# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
+
+
+REPOS="$1"
+TXN="$2"
+
+# Make sure that the log message contains some text.
+SVNLOOK=/usr/local/bin/svnlook
+$SVNLOOK log -t "$TXN" "$REPOS" | \
+   grep "[a-zA-Z0-9]" > /dev/null || exit 1
+
+# Check that the author of this commit has the rights to perform
+# the commit on the files and directories being modified.
+commit-access-control.pl "$REPOS" "$TXN" commit-access-control.cfg || exit 1
+
+# All checks passed, so allow the commit.
+exit 0
Index: continuum-release2/src/test/scm_save/hooks/pre-lock.tmpl
===================================================================
--- continuum-release2/src/test/scm_save/hooks/pre-lock.tmpl	(revision 0)
+++ continuum-release2/src/test/scm_save/hooks/pre-lock.tmpl	(revision 0)
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+# PRE-LOCK HOOK
+#
+# The pre-lock hook is invoked before an exclusive lock is
+# created.  Subversion runs this hook by invoking a program 
+# (script, executable, binary, etc.) named 'pre-lock' (for which
+# this file is a template), with the following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] PATH         (the path in the repository about to be locked)
+#   [3] USER         (the user creating the lock)
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# If the hook program exits with success, the lock is created; but
+# if it exits with failure (non-zero), the lock action is aborted
+# and STDERR is returned to the client.
+
+# On a Unix system, the normal procedure is to have 'pre-lock'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'pre-lock' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'pre-lock.bat' or 'pre-lock.exe',
+# but the basic idea is the same.
+#
+# Here is an example hook script, for a Unix /bin/sh interpreter:
+
+REPOS="$1"
+PATH="$2"
+USER="$3"
+
+# If a lock exists and is owned by a different person, don't allow it
+# to be stolen (e.g., with 'svn lock --force ...').
+
+# (Maybe this script could send email to the lock owner?)
+SVNLOOK=/usr/local/bin/svnlook
+GREP=/bin/grep
+SED=/bin/sed
+
+LOCK_OWNER=`$SVNLOOK lock "$REPOS" "$PATH" | \
+            $GREP '^Owner: ' | $SED 's/Owner: //'`
+
+# If we get no result from svnlook, there's no lock, allow the lock to
+# happen:
+if [ "$LOCK_OWNER" == "" ]; then
+  exit 0
+fi
+
+# If the person locking matches the lock's owner, allow the lock to
+# happen:
+if [ "$LOCK_OWNER" == "$USER" ]; then
+  exit 0
+fi
+
+# Otherwise, we've got an owner mismatch, so return failure:
+echo "Error: $PATH already locked by ${LOCK_OWNER}." 1>&2
+exit 1
Index: continuum-release2/src/test/scm_save/hooks/post-unlock.tmpl
===================================================================
--- continuum-release2/src/test/scm_save/hooks/post-unlock.tmpl	(revision 0)
+++ continuum-release2/src/test/scm_save/hooks/post-unlock.tmpl	(revision 0)
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# POST-UNLOCK HOOK
+#
+# The post-unlock hook runs after a path is unlocked.  Subversion runs
+# this hook by invoking a program (script, executable, binary, etc.)
+# named 'post-unlock' (for which this file is a template) with the 
+# following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] USER         (the user who destroyed the lock)
+#
+# The paths that were just unlocked are passed to the hook via STDIN
+# (as of Subversion 1.2, only one path is passed per invocation, but
+# the plan is to pass all unlocked paths at once, so the hook program
+# should be written accordingly).
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# Because the lock has already been destroyed and cannot be undone,
+# the exit code of the hook program is ignored.
+#
+# On a Unix system, the normal procedure is to have 'post-unlock'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'post-unlock' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'post-unlock.bat' or 'post-unlock.exe',
+# but the basic idea is the same.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter:
+
+REPOS="$1"
+USER="$2"
+
+# Send email to interested parties, let them know a lock was removed:
+mailer.py unlock "$REPOS" "$USER" /path/to/mailer.conf
Index: continuum-release2/src/test/scm_save/hooks/pre-unlock.tmpl
===================================================================
--- continuum-release2/src/test/scm_save/hooks/pre-unlock.tmpl	(revision 0)
+++ continuum-release2/src/test/scm_save/hooks/pre-unlock.tmpl	(revision 0)
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+# PRE-UNLOCK HOOK
+#
+# The pre-unlock hook is invoked before an exclusive lock is
+# destroyed.  Subversion runs this hook by invoking a program 
+# (script, executable, binary, etc.) named 'pre-unlock' (for which
+# this file is a template), with the following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] PATH         (the path in the repository about to be unlocked)
+#   [3] USER         (the user destroying the lock)
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# If the hook program exits with success, the lock is destroyed; but
+# if it exits with failure (non-zero), the unlock action is aborted
+# and STDERR is returned to the client.
+
+# On a Unix system, the normal procedure is to have 'pre-unlock'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'pre-unlock' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'pre-unlock.bat' or 'pre-unlock.exe',
+# but the basic idea is the same.
+#
+# Here is an example hook script, for a Unix /bin/sh interpreter:
+
+REPOS="$1"
+PATH="$2"
+USER="$3"
+
+# If a lock is owned by a different person, don't allow it be broken.
+# (Maybe this script could send email to the lock owner?)
+
+SVNLOOK=/usr/local/bin/svnlook
+GREP=/bin/grep
+SED=/bin/sed
+
+LOCK_OWNER=`$SVNLOOK lock "$REPOS" "$PATH" | \
+            $GREP '^Owner: ' | $SED 's/Owner: //'`
+
+# If we get no result from svnlook, there's no lock, return success:
+if [ "$LOCK_OWNER" == "" ]; then
+  exit 0
+fi
+# If the person unlocking matches the lock's owner, return success:
+if [ "$LOCK_OWNER" == "$USER" ]; then
+  exit 0
+fi
+
+# Otherwise, we've got an owner mismatch, so return failure:
+echo "Error: $PATH locked by ${LOCK_OWNER}." 1>&2
+exit 1
Index: continuum-release2/src/test/scm_save/hooks/post-revprop-change.tmpl
===================================================================
--- continuum-release2/src/test/scm_save/hooks/post-revprop-change.tmpl	(revision 0)
+++ continuum-release2/src/test/scm_save/hooks/post-revprop-change.tmpl	(revision 0)
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+# POST-REVPROP-CHANGE HOOK
+#
+# The post-revprop-change hook is invoked after a revision property
+# has been added, modified or deleted.  Subversion runs this hook by
+# invoking a program (script, executable, binary, etc.) named
+# 'post-revprop-change' (for which this file is a template), with the
+# following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] REV          (the revision that was tweaked)
+#   [3] USER         (the username of the person tweaking the property)
+#   [4] PROPNAME     (the property that was changed)
+#   [5] ACTION       (the property was 'A'dded, 'M'odified, or 'D'eleted)
+#
+#   [STDIN] PROPVAL  ** the old property value is passed via STDIN.
+#
+# Because the propchange has already completed and cannot be undone,
+# the exit code of the hook program is ignored.  The hook program
+# can use the 'svnlook' utility to help it examine the
+# new property value.
+#
+# On a Unix system, the normal procedure is to have 'post-revprop-change'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'post-revprop-change' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'post-revprop-change.bat' or 'post-revprop-change.exe',
+# but the basic idea is the same.
+# 
+# The hook program typically does not inherit the environment of
+# its parent process.  For example, a common problem is for the
+# PATH environment variable to not be set to its usual value, so
+# that subprograms fail to launch unless invoked via absolute path.
+# If you're having unexpected problems with a hook program, the
+# culprit may be unusual (or missing) environment variables.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter.
+# For more examples and pre-written hooks, see those in
+# the Subversion repository at
+# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
+# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
+
+
+REPOS="$1"
+REV="$2"
+USER="$3"
+PROPNAME="$4"
+ACTION="$5"
+
+propchange-email.pl "$REPOS" "$REV" "$USER" "$PROPNAME" watchers@example.org
Index: continuum-release2/src/test/scm_save/hooks/start-commit.tmpl
===================================================================
--- continuum-release2/src/test/scm_save/hooks/start-commit.tmpl	(revision 0)
+++ continuum-release2/src/test/scm_save/hooks/start-commit.tmpl	(revision 0)
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+# START-COMMIT HOOK
+#
+# The start-commit hook is invoked before a Subversion txn is created
+# in the process of doing a commit.  Subversion runs this hook
+# by invoking a program (script, executable, binary, etc.) named
+# 'start-commit' (for which this file is a template)
+# with the following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] USER         (the authenticated user attempting to commit)
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# If the hook program exits with success, the commit continues; but
+# if it exits with failure (non-zero), the commit is stopped before
+# a Subversion txn is created, and STDERR is returned to the client.
+#
+# On a Unix system, the normal procedure is to have 'start-commit'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'start-commit' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'start-commit.bat' or 'start-commit.exe',
+# but the basic idea is the same.
+# 
+# The hook program typically does not inherit the environment of
+# its parent process.  For example, a common problem is for the
+# PATH environment variable to not be set to its usual value, so
+# that subprograms fail to launch unless invoked via absolute path.
+# If you're having unexpected problems with a hook program, the
+# culprit may be unusual (or missing) environment variables.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter.
+# For more examples and pre-written hooks, see those in
+# the Subversion repository at
+# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
+# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
+
+
+REPOS="$1"
+USER="$2"
+
+commit-allower.pl --repository "$REPOS" --user "$USER" || exit 1
+special-auth-check.py --user "$USER" --auth-level 3 || exit 1
+
+# All checks passed, so allow the commit.
+exit 0
Index: continuum-release2/src/test/scm_save/conf/svnserve.conf
===================================================================
--- continuum-release2/src/test/scm_save/conf/svnserve.conf	(revision 0)
+++ continuum-release2/src/test/scm_save/conf/svnserve.conf	(revision 0)
@@ -0,0 +1,30 @@
+### This file controls the configuration of the svnserve daemon, if you
+### use it to allow access to this repository.  (If you only allow
+### access through http: and/or file: URLs, then this file is
+### irrelevant.)
+
+### Visit http://subversion.tigris.org/ for more information.
+
+# [general]
+### These options control access to the repository for unauthenticated
+### and authenticated users.  Valid values are "write", "read",
+### and "none".  The sample settings below are the defaults.
+# anon-access = read
+# auth-access = write
+### The password-db option controls the location of the password
+### database file.  Unless you specify a path starting with a /,
+### the file's location is relative to the conf directory.
+### Uncomment the line below to use the default password file.
+# password-db = passwd
+### The authz-db option controls the location of the authorization
+### rules for path-based access control.  Unless you specify a path
+### starting with a /, the file's location is relative to the conf
+### directory.  If you don't specify an authz-db, no path-based access
+### control is done.
+### Uncomment the line below to use the default authorization file.
+# authz-db = authz
+### This option specifies the authentication realm of the repository.
+### If two repositories have the same authentication realm, they should
+### have the same password database, and vice versa.  The default realm
+### is repository's uuid.
+# realm = My First Repository
Index: continuum-release2/src/test/scm_save/conf/passwd
===================================================================
--- continuum-release2/src/test/scm_save/conf/passwd	(revision 0)
+++ continuum-release2/src/test/scm_save/conf/passwd	(revision 0)
@@ -0,0 +1,8 @@
+### This file is an example password file for svnserve.
+### Its format is similar to that of svnserve.conf. As shown in the
+### example below it contains one section labelled [users].
+### The name and password for each user follow, one account per line.
+
+# [users]
+# harry = harryssecret
+# sally = sallyssecret
Index: continuum-release2/src/test/scm_save/conf/authz
===================================================================
--- continuum-release2/src/test/scm_save/conf/authz	(revision 0)
+++ continuum-release2/src/test/scm_save/conf/authz	(revision 0)
@@ -0,0 +1,21 @@
+### This file is an example authorization file for svnserve.
+### Its format is identical to that of mod_authz_svn authorization
+### files.
+### As shown below each section defines authorizations for the path and
+### (optional) repository specified by the section name.
+### The authorizations follow. An authorization line can refer to a
+### single user, to a group of users defined in a special [groups]
+### section, or to anyone using the '*' wildcard.  Each definition can
+### grant read ('r') access, read-write ('rw') access, or no access
+### ('').
+
+# [groups]
+# harry_and_sally = harry,sally
+
+# [/foo/bar]
+# harry = rw
+# * =
+
+# [repository:/baz/fuz]
+# @harry_and_sally = rw
+# * = r
Index: continuum-release2/src/test/scm_save/db/revs/0
===================================================================
--- continuum-release2/src/test/scm_save/db/revs/0	(revision 0)
+++ continuum-release2/src/test/scm_save/db/revs/0	(revision 0)
@@ -0,0 +1,11 @@
+PLAIN
+END
+ENDREP
+id: 0.0.r0/17
+type: dir
+count: 0
+text: 0 0 4 4 2d2977d1c96f487abe4a1e202dd03b4e
+cpath: /
+
+
+17 107
Index: continuum-release2/src/test/scm_save/db/revs/1
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: continuum-release2/src/test/scm_save/db/revs/1
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: continuum-release2/src/test/scm_save/db/revs/2
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: continuum-release2/src/test/scm_save/db/revs/2
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: continuum-release2/src/test/scm_save/db/revprops/0
===================================================================
--- continuum-release2/src/test/scm_save/db/revprops/0	(revision 0)
+++ continuum-release2/src/test/scm_save/db/revprops/0	(revision 0)
@@ -0,0 +1,5 @@
+K 8
+svn:date
+V 27
+2006-09-06T07:29:54.984375Z
+END
Index: continuum-release2/src/test/scm_save/db/revprops/1
===================================================================
--- continuum-release2/src/test/scm_save/db/revprops/1	(revision 0)
+++ continuum-release2/src/test/scm_save/db/revprops/1	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 4
+User
+K 8
+svn:date
+V 27
+2006-09-06T07:31:44.109375Z
+K 7
+svn:log
+V 8
+new file
+END
Index: continuum-release2/src/test/scm_save/db/revprops/2
===================================================================
--- continuum-release2/src/test/scm_save/db/revprops/2	(revision 0)
+++ continuum-release2/src/test/scm_save/db/revprops/2	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 4
+User
+K 8
+svn:date
+V 27
+2006-09-06T08:23:37.671875Z
+K 7
+svn:log
+V 0
+
+END
Index: continuum-release2/src/test/scm_save/db/write-lock
===================================================================
Index: continuum-release2/src/test/scm_save/db/current
===================================================================
--- continuum-release2/src/test/scm_save/db/current	(revision 0)
+++ continuum-release2/src/test/scm_save/db/current	(revision 0)
@@ -0,0 +1 @@
+2 5 1
Index: continuum-release2/src/test/scm_save/db/uuid
===================================================================
--- continuum-release2/src/test/scm_save/db/uuid	(revision 0)
+++ continuum-release2/src/test/scm_save/db/uuid	(revision 0)
@@ -0,0 +1 @@
+edc627db-db88-0d49-b1b3-a930d7181127
Index: continuum-release2/src/test/scm_save/db/fs-type
===================================================================
--- continuum-release2/src/test/scm_save/db/fs-type	(revision 0)
+++ continuum-release2/src/test/scm_save/db/fs-type	(revision 0)
@@ -0,0 +1 @@
+fsfs
Index: continuum-release2/src/test/scm_save/db/transactions/readme.txt
===================================================================
--- continuum-release2/src/test/scm_save/db/transactions/readme.txt	(revision 0)
+++ continuum-release2/src/test/scm_save/db/transactions/readme.txt	(revision 0)
@@ -0,0 +1 @@
+this file is here so that the resources plugin will copy this directory. It doesn't copy empty directories.
Index: continuum-release2/src/test/scm_save/db/format
===================================================================
--- continuum-release2/src/test/scm_save/db/format	(revision 0)
+++ continuum-release2/src/test/scm_save/db/format	(revision 0)
@@ -0,0 +1 @@
+1
Index: continuum-release2/src/test/scm_save/format
===================================================================
--- continuum-release2/src/test/scm_save/format	(revision 0)
+++ continuum-release2/src/test/scm_save/format	(revision 0)
@@ -0,0 +1 @@
+3
Index: continuum-release2/src/test/scm_save/locks/db.lock
===================================================================
--- continuum-release2/src/test/scm_save/locks/db.lock	(revision 0)
+++ continuum-release2/src/test/scm_save/locks/db.lock	(revision 0)
@@ -0,0 +1,3 @@
+This file is not used by Subversion 1.3.x or later.
+However, its existence is required for compatibility with
+Subversion 1.2.x or earlier.
Index: continuum-release2/src/test/scm_save/locks/db-logs.lock
===================================================================
--- continuum-release2/src/test/scm_save/locks/db-logs.lock	(revision 0)
+++ continuum-release2/src/test/scm_save/locks/db-logs.lock	(revision 0)
@@ -0,0 +1,3 @@
+This file is not used by Subversion 1.3.x or later.
+However, its existence is required for compatibility with
+Subversion 1.2.x or earlier.
Index: continuum-release2/src/test/scm_save/README.txt
===================================================================
--- continuum-release2/src/test/scm_save/README.txt	(revision 0)
+++ continuum-release2/src/test/scm_save/README.txt	(revision 0)
@@ -0,0 +1,5 @@
+This is a Subversion repository; use the 'svnadmin' tool to examine
+it.  Do not add, delete, or modify files here unless you know how
+to avoid corrupting the repository.
+
+Visit http://subversion.tigris.org/ for more information.
Index: continuum-release2/src/test/java/org/apache/maven/continuum/release/TestExecuteRelease.java
===================================================================
--- continuum-release2/src/test/java/org/apache/maven/continuum/release/TestExecuteRelease.java	(revision 0)
+++ continuum-release2/src/test/java/org/apache/maven/continuum/release/TestExecuteRelease.java	(revision 0)
@@ -0,0 +1,506 @@
+package org.apache.maven.continuum.release;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.release.bean.ReleaseDependency;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor;
+import org.apache.maven.continuum.release.bean.ReleaseProject;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor.Status;
+import org.apache.maven.continuum.release.task.ReleaseTask;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.scm.ScmBranch;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.command.checkout.CheckOutScmResult;
+import org.apache.maven.scm.command.list.ListScmResult;
+import org.apache.maven.scm.manager.NoSuchScmProviderException;
+import org.apache.maven.scm.manager.ScmManager;
+import org.apache.maven.scm.repository.ScmRepository;
+import org.apache.maven.scm.repository.ScmRepositoryException;
+import org.codehaus.plexus.PlexusContainerException;
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.taskqueue.TaskQueueException;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutor;
+import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
+import org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.cli.WriterStreamConsumer;
+
+public class TestExecuteRelease extends PlexusTestCase {
+	Logger logger = Logger.getLogger(TestExecuteRelease.class);
+	ScmManager scmManager;
+	TaskExecutor releaseExecutor;
+	ThreadedTaskQueueExecutor releaseProjectExecutor;
+	ProjectReleaseManager releaseManager;
+	
+	private ScmRepository getScmRepositorty(String project)
+			throws ScmRepositoryException, NoSuchScmProviderException {
+		String scmPath = new File(getBasedir(), "target/scm-test/" + project)
+				.getAbsolutePath().replace('\\', '/');
+
+		String scmUrl = "scm:svn:file:///" + scmPath + "/trunk";
+
+		ScmRepository repository = scmManager.makeScmRepository(scmUrl.trim());
+
+		repository.getProviderRepository().setPersistCheckout(true);
+
+		return repository;
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		scmManager = (ScmManager) lookup(ScmManager.class);
+		releaseProjectExecutor = (ThreadedTaskQueueExecutor)lookup(TaskQueueExecutor.class,"releaseProject2");
+		lookup(TaskQueueExecutor.class,"release2");
+		releaseExecutor = (TaskExecutor) lookup(
+				TaskExecutor.class, "release2");
+		releaseManager = (ProjectReleaseManager)lookup(ProjectReleaseManager.class);
+		
+		File scmPath = new File(getBasedir(), "target/scm-src").getAbsoluteFile();
+		File scmTargetPath = new File(getBasedir(), "target/scm-test").getAbsoluteFile();
+		FileUtils.copyDirectoryStructure(scmPath, scmTargetPath);
+		FileUtils.deleteDirectory("target/build");
+	}
+	@Override
+	protected void tearDown() throws Exception {
+		super.tearDown();
+		releaseProjectExecutor.stop();
+		
+	}
+	/**
+	 * @param args
+	 * @throws TaskQueueException
+	 * @throws PlexusContainerException
+	 */
+	public void testReleaseSimpleProject() throws Exception {
+		super.setUp();
+		// String scmPath = new File(getBasedir(),
+		// "target/scm-src/simple").getAbsolutePath().replace('\\', '/');
+
+		ScmRepository repository = getScmRepositorty("simple");
+		String scmPath = new File(getBasedir(), "target/scm-test/" + "simple")
+				.getAbsolutePath().replace('\\', '/');
+
+		ReleaseDescriptor descriptor = new ReleaseDescriptor();
+
+		descriptor.setBuildDirectory("target/build/");
+		descriptor.setWorkingDirectory(new File(descriptor.getBuildDirectory(), "1"));
+		if(!descriptor.getWorkingDirectory().exists())
+			descriptor.getWorkingDirectory().mkdirs();
+		descriptor.setPassword("decherfb");
+		List<ReleaseProject> projectsToRelease = new ArrayList<ReleaseProject>();
+		descriptor.setProjectsToRelease(projectsToRelease);
+		descriptor.setReleaseTag("${project.artifactId}_${project.version}");
+		descriptor.setNextDevelopmentVersion("1.0.1-SNAPSHOT");
+		descriptor.setReleaseVersion("1.0.0");
+		descriptor.setUsername("decherfb");
+		descriptor.setPerformRelease(true);
+		descriptor.setPrepareRelease(true);
+
+		ReleaseProject project = new ReleaseProject();
+		Project p = new Project();
+		p.setArtifactId("simple");
+		p.setGroupId("test");
+		p.setVersion("1.0-SNAPSHOT");
+		// p.setScmUrl("scm:cvs|pserver|decherfb@cvs-2.kelkoo.net|2404|/home/y/share/cvs-repository/MT_demo|ciTrainingCommon");
+		p.setScmUrl("scm:svn:file:///" + scmPath + "/trunk");
+
+		project.setProject(p);
+		project.setProjectDirectory(new File("target/build/1/simple"));
+		project.setOutputLog(new File("target/build/1/simple.log"));
+		
+		project.setStreamConsumer(new WriterStreamConsumer(new PrintWriter(System.out)));
+		project.setReleaseTag("${project.artifactId}_${project.version}");
+		project.setNextDevelopmentVersion("1.0.1-SNAPSHOT");
+		project.setReleaseVersion("1.0.0");
+		
+		project.setScmRepository(getScmRepositorty("simple"));
+		projectsToRelease.add(project);
+
+		ReleaseTask task = new ReleaseTask(descriptor);
+		//releaseExecutor.executeTask(task);
+		releaseManager.releaseProjects(descriptor);
+		
+		for (ReleaseProject releaseProject : descriptor.getProjectsToRelease()) {
+			logger.info(releaseProject.getProject().getArtifactId() + ": "
+					+ releaseProject.getStatus());
+			while(releaseProject.getStatus() == null || releaseProject.getStatus().compareTo(Status.PERFORM_SUCCESS)<0)
+				Thread.sleep(100);
+			assertEquals(Status.PERFORM_SUCCESS, releaseProject.getStatus());
+		}
+
+		
+		File checkoutProjectDir = new File("target/scm-validation");
+		checkoutProjectDir.mkdirs();
+		scmManager.checkOut(repository, new ScmFileSet(checkoutProjectDir));
+		MavenXpp3Reader reader = new MavenXpp3Reader();
+		Model pom = reader.read(new InputStreamReader(new FileInputStream(
+				"target/scm-validation/pom.xml")));
+		assertEquals("1.0.1-SNAPSHOT", pom.getVersion());
+		// check for tag.
+
+		ScmRepository repositoryTags = getScmRepositorty("scm:svn:file:///"
+				+ scmPath + "/tags/simple_1-0-0");
+		ScmFileSet fileSet = new ScmFileSet(new File("/"));
+		fileSet.getFileList().add(new File("/"));
+		ListScmResult result = scmManager.list(repositoryTags, fileSet, false,
+				null);
+		assertNotNull(result.getFiles());
+		System.out.println("tags :" + result.getFiles());
+
+	}
+
+	public void testRelease2SimpleProjects() throws Exception {
+		super.setUp();
+		String scmPath = new File(getBasedir(), "target/scm-test/")
+				.getAbsolutePath().replace('\\', '/');
+
+		ScmRepository repository = getScmRepositorty("simple");
+
+		ReleaseDescriptor descriptor = new ReleaseDescriptor();
+
+		descriptor.setBuildDirectory("target/build/");
+		descriptor.setNextDevelopmentVersion("1.0.1-SNAPSHOT");
+		descriptor.setPassword("decherfb");
+		List<ReleaseProject> projectsToRelease = new ArrayList<ReleaseProject>();
+		descriptor.setProjectsToRelease(projectsToRelease);
+		descriptor.setReleaseTag("${project.artifactId}_${project.version}");
+		descriptor.setReleaseVersion("1.0.0");
+		descriptor.setUsername("decherfb");
+		descriptor.setPerformRelease(true);
+		descriptor.setPrepareRelease(true);
+
+		ReleaseProject project = new ReleaseProject();
+		Project p = new Project();
+		p.setArtifactId("simple");
+		p.setGroupId("test");
+		p.setVersion("1.0-SNAPSHOT");
+		// p.setScmUrl("scm:cvs|pserver|decherfb@cvs-2.kelkoo.net|2404|/home/y/share/cvs-repository/MT_demo|ciTrainingCommon");
+		p.setScmUrl("scm:svn:file:///" + scmPath + "/simple" + "/trunk");
+
+		project.setProject(p);
+		projectsToRelease.add(project);
+
+		ReleaseProject project2 = new ReleaseProject();
+		Project p2 = new Project();
+		p2.setArtifactId("A");
+		p2.setGroupId("test");
+		p2.setVersion("1.0-SNAPSHOT");
+		// p.setScmUrl("scm:cvs|pserver|decherfb@cvs-2.kelkoo.net|2404|/home/y/share/cvs-repository/MT_demo|ciTrainingCommon");
+		p2.setScmUrl("scm:svn:file:///" + scmPath + "/A" + "/trunk");
+
+		project2.setProject(p2);
+		projectsToRelease.add(project2);
+		
+		releaseManager.releaseProjects(descriptor);
+
+		for (ReleaseProject releaseProject : descriptor.getProjectsToRelease()) {
+			while(releaseProject.getStatus() == null || releaseProject.getStatus().compareTo(Status.PERFORM_SUCCESS)<0)
+				Thread.sleep(100);
+			logger.info(releaseProject.getProject().getArtifactId() + ": "
+					+ releaseProject.getStatus());
+			assertEquals(Status.PERFORM_SUCCESS, releaseProject.getStatus());
+
+		}
+
+		checkProject(repository, scmPath + "simple", "simple_1-0-0", "simple", "1.0.1-SNAPSHOT");
+		checkProject(getScmRepositorty("A"), scmPath + "A", "A_1-0-0", "A", "1.0.1-SNAPSHOT");
+	}
+	
+	public void testRelease2ProjectsWithDependencies() throws Exception {
+		super.setUp();
+		String scmPath = new File(getBasedir(), "target/scm-test/")
+				.getAbsolutePath().replace('\\', '/');
+
+		ScmRepository repository = getScmRepositorty("B");
+
+		ReleaseDescriptor descriptor = new ReleaseDescriptor();
+
+		descriptor.setBuildDirectory("target/build/");
+		
+		descriptor.setNextDevelopmentVersion("1.0.1-SNAPSHOT");
+		descriptor.setPassword("decherfb");
+		List<ReleaseProject> projectsToRelease = new ArrayList<ReleaseProject>();
+		descriptor.setProjectsToRelease(projectsToRelease);
+		descriptor.setReleaseTag("${project.artifactId}_${project.version}");
+		descriptor.setReleaseVersion("1.0.0");
+		descriptor.setUsername("decherfb");
+		descriptor.setPerformRelease(true);
+		descriptor.setPrepareRelease(true);
+
+		ReleaseProject project = new ReleaseProject();
+		Project p = new Project();
+		p.setArtifactId("B");
+		p.setGroupId("test");
+		p.setVersion("1.0-SNAPSHOT");
+		// p.setScmUrl("scm:cvs|pserver|decherfb@cvs-2.kelkoo.net|2404|/home/y/share/cvs-repository/MT_demo|ciTrainingCommon");
+		p.setScmUrl("scm:svn:file:///" + scmPath + "/B" + "/trunk");
+
+		project.setProject(p);
+		projectsToRelease.add(project);
+
+		ReleaseProject project2 = new ReleaseProject();
+		Project p2 = new Project();
+		p2.setArtifactId("A");
+		p2.setGroupId("test");
+		p2.setVersion("1.0-SNAPSHOT");
+		// p.setScmUrl("scm:cvs|pserver|decherfb@cvs-2.kelkoo.net|2404|/home/y/share/cvs-repository/MT_demo|ciTrainingCommon");
+		p2.setScmUrl("scm:svn:file:///" + scmPath + "/A" + "/trunk");
+
+		project2.setProject(p2);
+		projectsToRelease.add(project2);
+		
+		releaseManager.releaseProjects(descriptor);
+
+		for (ReleaseProject releaseProject : descriptor.getProjectsToRelease()) {
+			while(releaseProject.getStatus() == null || releaseProject.getStatus().compareTo(Status.PERFORM_SUCCESS)<0)
+				Thread.sleep(100);
+			logger.info(releaseProject.getProject().getArtifactId() + ": "
+					+ releaseProject.getStatus());
+			assertEquals(Status.PERFORM_SUCCESS, releaseProject.getStatus());
+
+		}
+
+		checkProject(repository, scmPath + "B", "B_1-0-0", "B", "1.0.1-SNAPSHOT");
+		checkProject(getScmRepositorty("A"), scmPath + "A", "A_1-0-0", "A", "1.0.1-SNAPSHOT");
+	}
+
+	public void testReleaseProjectsWithSnapshotDependency() throws Exception {
+		super.setUp();
+		String scmPath = new File(getBasedir(), "target/scm-test/")
+				.getAbsolutePath().replace('\\', '/');
+
+		ScmRepository repository = getScmRepositorty("B");
+
+		ReleaseDescriptor descriptor = new ReleaseDescriptor();
+
+		descriptor.setBuildDirectory("target/build/");
+		
+		descriptor.setNextDevelopmentVersion("1.0.1-SNAPSHOT");
+		descriptor.setPassword("decherfb");
+		List<ReleaseProject> projectsToRelease = new ArrayList<ReleaseProject>();
+		descriptor.setProjectsToRelease(projectsToRelease);
+		descriptor.setReleaseTag("${project.artifactId}_${project.version}");
+		descriptor.setReleaseVersion("1.0.0");
+		descriptor.setUsername("decherfb");
+		descriptor.setPerformRelease(true);
+		descriptor.setPrepareRelease(true);
+
+		ReleaseProject project = new ReleaseProject();
+		Project p = new Project();
+		p.setArtifactId("B");
+		p.setGroupId("test");
+		p.setVersion("1.0-SNAPSHOT");
+		// p.setScmUrl("scm:cvs|pserver|decherfb@cvs-2.kelkoo.net|2404|/home/y/share/cvs-repository/MT_demo|ciTrainingCommon");
+		p.setScmUrl("scm:svn:file:///" + scmPath + "/B" + "/trunk");
+
+		project.setProject(p);
+		projectsToRelease.add(project);
+
+		releaseManager.releaseProjects(descriptor);
+
+		for (ReleaseProject releaseProject : descriptor.getProjectsToRelease()) {
+			while(releaseProject.getStatus() == null || releaseProject.getStatus().compareTo(Status.CHECKOUT_SUCCESS)<0)
+				Thread.sleep(100);
+			Thread.sleep(1000);
+			logger.info(releaseProject.getProject().getArtifactId() + ": "
+					+ releaseProject.getStatus());
+		}
+		assertNotNull(descriptor.getSnapshotDependencies());
+		assertFalse(descriptor.getSnapshotDependencies().isEmpty());
+		assertEquals(1, descriptor.getSnapshotDependencies().size());
+		ReleaseDependency releaseDep = descriptor.getSnapshotDependencies().iterator().next();
+		assertEquals("A", releaseDep.getArtifactId());
+		
+		releaseDep.setNextDevVersion("1.2-SNAPSHOT");
+		releaseDep.setReleaseVersion("1.1");
+		releaseManager.releaseProjects(descriptor);
+
+		for (ReleaseProject releaseProject : descriptor.getProjectsToRelease()) {
+			while(releaseProject.getStatus() == null || releaseProject.getStatus().compareTo(Status.PERFORM_SUCCESS)<0)
+				Thread.sleep(100);
+			logger.info(releaseProject.getProject().getArtifactId() + ": "
+					+ releaseProject.getStatus());
+			assertEquals(Status.PERFORM_SUCCESS, releaseProject.getStatus());
+
+		}
+
+		checkProject(repository, scmPath + "B", "B_1-0-0", "B", "1.0.1-SNAPSHOT");
+	}
+	
+	void checkProject(ScmRepository repository, String scmPath, String tag, String project, String devVersion) throws Exception {
+		File checkoutProjectDir = new File("target/scm-validation/"+ project);
+		checkoutProjectDir.mkdirs();
+		scmManager.checkOut(repository, new ScmFileSet(checkoutProjectDir));
+		MavenXpp3Reader reader = new MavenXpp3Reader();
+		Model pom = reader.read(new InputStreamReader(new FileInputStream(
+				"target/scm-validation/" + project + "/pom.xml")));
+		assertEquals(devVersion, pom.getVersion());
+		// check for tag.
+
+		ScmRepository repositoryTags = getScmRepositorty("scm:svn:file:///"
+				+ scmPath + "/tags/" + tag);
+		ScmFileSet fileSet = new ScmFileSet(new File("/"));
+		fileSet.getFileList().add(new File("/"));
+		ListScmResult result = scmManager.list(repositoryTags, fileSet, false,
+				null);
+		assertNotNull(result.getFiles());
+		System.out.println("tags :" + result.getFiles());
+
+	}
+
+	public void testReleaseFromTag() throws Exception {
+		super.setUp();
+		// String scmPath = new File(getBasedir(),
+		// "target/scm-src/simple").getAbsolutePath().replace('\\', '/');
+		String strProject = "fromTag";
+		ScmRepository repository = getScmRepositorty("fromTag");
+		String scmPath = new File(getBasedir(), "target/scm-test/" + strProject)
+				.getAbsolutePath().replace('\\', '/');
+
+		ReleaseDescriptor descriptor = new ReleaseDescriptor();
+
+		descriptor.setBuildDirectory("target/build/");
+		descriptor.setNextDevelopmentVersion("1.0.1-SNAPSHOT");
+		descriptor.setPassword("decherfb");
+		List<ReleaseProject> projectsToRelease = new ArrayList<ReleaseProject>();
+		descriptor.setProjectsToRelease(projectsToRelease);
+		descriptor.setReleaseTag("${project.artifactId}_${project.version}");
+		descriptor.setReleaseVersion("1.0.0");
+		descriptor.setFromVersion("nightly");
+		descriptor.setBranchName("branch_${project.artifactId}_${project.version}");
+		descriptor.setVersionType("tag");
+		descriptor.setUsername("decherfb");
+		descriptor.setPerformRelease(true);
+		descriptor.setPrepareRelease(true);
+
+		ReleaseProject project = new ReleaseProject();
+		Project p = new Project();
+		p.setArtifactId(strProject);
+		p.setGroupId("test");
+		p.setVersion("1.0-SNAPSHOT");
+		// p.setScmUrl("scm:cvs|pserver|decherfb@cvs-2.kelkoo.net|2404|/home/y/share/cvs-repository/MT_demo|ciTrainingCommon");
+		p.setScmUrl("scm:svn:file:///" + scmPath + "/trunk");
+
+		project.setProject(p);
+		projectsToRelease.add(project);
+
+		releaseManager.releaseProjects(descriptor);
+
+		for (ReleaseProject releaseProject : descriptor.getProjectsToRelease()) {
+			while(releaseProject.getStatus() == null || releaseProject.getStatus().compareTo(Status.PERFORM_SUCCESS)<0)
+				Thread.sleep(100);
+			logger.info(releaseProject.getProject().getArtifactId() + ": "
+					+ releaseProject.getStatus());
+			assertEquals(Status.PERFORM_SUCCESS, releaseProject.getStatus());
+		}
+
+		
+		File checkoutProjectDir = new File("target/scm-validation");
+		checkoutProjectDir.mkdirs();
+		ScmBranch scmBranch = new ScmBranch("branch_fromTag_1-0-0");
+		scmManager.checkOut(repository, new ScmFileSet(checkoutProjectDir), scmBranch);
+		MavenXpp3Reader reader = new MavenXpp3Reader();
+		Model pom = reader.read(new InputStreamReader(new FileInputStream(
+				"target/scm-validation/pom.xml")));
+		assertEquals("1.0.1-SNAPSHOT", pom.getVersion());
+		// check for tag.
+
+		scmPath = getBasedir()+ "/target/scm-test/" + project;
+
+		String scmUrl = "scm:svn:file:///"
+			+ scmPath + "/tags/fromTag_1-0-0";
+
+		ScmRepository repositoryTags = scmManager.makeScmRepository(scmUrl.trim());
+
+		ScmFileSet fileSet = new ScmFileSet(new File("/"));
+		fileSet.getFileList().add(new File("/"));
+		ListScmResult result = scmManager.list(repositoryTags, fileSet, false,
+				null);
+		assertNotNull(result.getFiles());
+		System.out.println("tags :" + result.getFiles());
+
+	}
+
+	public void testReleaseRollbackProject() throws Exception {
+		super.setUp();
+		// String scmPath = new File(getBasedir(),
+		// "target/scm-src/simple").getAbsolutePath().replace('\\', '/');
+
+		ScmRepository repository = getScmRepositorty("rollbackTest");
+		String scmPath = new File(getBasedir(), "target/scm-test/" + "rollbackTest")
+				.getAbsolutePath().replace('\\', '/');
+
+		ReleaseDescriptor descriptor = new ReleaseDescriptor();
+
+		descriptor.setBuildDirectory("target/build/");
+		descriptor.setWorkingDirectory(new File(descriptor.getBuildDirectory(), "1"));
+		if(!descriptor.getWorkingDirectory().exists())
+			descriptor.getWorkingDirectory().mkdirs();
+		descriptor.setPassword("decherfb");
+		List<ReleaseProject> projectsToRelease = new ArrayList<ReleaseProject>();
+		descriptor.setProjectsToRelease(projectsToRelease);
+		descriptor.setReleaseTag("${project.artifactId}_${project.version}");
+		descriptor.setNextDevelopmentVersion("1.0.1-SNAPSHOT");
+		descriptor.setReleaseVersion("1.0.0");
+		descriptor.setUsername("decherfb");
+		descriptor.setPerformRelease(true);
+		descriptor.setPrepareRelease(true);
+
+		ReleaseProject project = new ReleaseProject();
+		Project p = new Project();
+		p.setArtifactId("rollbackTest");
+		p.setGroupId("test");
+		p.setVersion("1.0-SNAPSHOT");
+		// p.setScmUrl("scm:cvs|pserver|decherfb@cvs-2.kelkoo.net|2404|/home/y/share/cvs-repository/MT_demo|ciTrainingCommon");
+		p.setScmUrl("scm:svn:file:///" + scmPath + "/trunk");
+
+		project.setProject(p);
+		project.setProjectDirectory(new File("target/build/1/rollbackTest"));
+		project.setOutputLog(new File("target/build/1/rollbackTest.log"));
+		
+		project.setStreamConsumer(new WriterStreamConsumer(new PrintWriter(System.out)));
+		project.setReleaseTag("${project.artifactId}_${project.version}");
+		project.setNextDevelopmentVersion("1.0.1-SNAPSHOT");
+		project.setReleaseVersion("1.0.0");
+		
+		project.setScmRepository(getScmRepositorty("rollbackTest"));
+		projectsToRelease.add(project);
+
+		ReleaseTask task = new ReleaseTask(descriptor);
+		//releaseExecutor.executeTask(task);
+		releaseManager.releaseProjects(descriptor);
+		
+		for (ReleaseProject releaseProject : descriptor.getProjectsToRelease()) {
+			logger.info(releaseProject.getProject().getArtifactId() + ": "
+					+ releaseProject.getStatus());
+			int time = 0;
+			while(time < 120000 && (releaseProject.getStatus() == null || releaseProject.getStatus().compareTo(Status.ROLLBACK_SUCCESS)<0)) {
+				Thread.sleep(100);
+				time += 100;
+			}
+			assertEquals(Status.ROLLBACK_SUCCESS, releaseProject.getStatus());
+		}
+
+		
+		File checkoutProjectDir = new File("target/scm-validation/rollbackTest" );
+		checkoutProjectDir.mkdirs();
+		CheckOutScmResult result = scmManager.checkOut(repository, new ScmFileSet(checkoutProjectDir));
+		if(!result.isSuccess())
+			throw new Exception("test fails : " + result.getCommandOutput());
+		MavenXpp3Reader reader = new MavenXpp3Reader();
+		Model pom = reader.read(new InputStreamReader(new FileInputStream(
+				"target/scm-validation/rollbackTest/pom.xml")));
+		assertEquals("1.0-SNAPSHOT", pom.getVersion());
+		// check for tag.
+	}
+
+}
Index: continuum-release2/src/test/scm/hooks/pre-revprop-change.tmpl
===================================================================
--- continuum-release2/src/test/scm/hooks/pre-revprop-change.tmpl	(revision 0)
+++ continuum-release2/src/test/scm/hooks/pre-revprop-change.tmpl	(revision 0)
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+# PRE-REVPROP-CHANGE HOOK
+#
+# The pre-revprop-change hook is invoked before a revision property
+# is added, modified or deleted.  Subversion runs this hook by invoking
+# a program (script, executable, binary, etc.) named 'pre-revprop-change'
+# (for which this file is a template), with the following ordered
+# arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] REVISION     (the revision being tweaked)
+#   [3] USER         (the username of the person tweaking the property)
+#   [4] PROPNAME     (the property being set on the revision)
+#   [5] ACTION       (the property is being 'A'dded, 'M'odified, or 'D'eleted)
+#
+#   [STDIN] PROPVAL  ** the new property value is passed via STDIN.
+#
+# If the hook program exits with success, the propchange happens; but
+# if it exits with failure (non-zero), the propchange doesn't happen.
+# The hook program can use the 'svnlook' utility to examine the 
+# existing value of the revision property.
+#
+# WARNING: unlike other hooks, this hook MUST exist for revision
+# properties to be changed.  If the hook does not exist, Subversion 
+# will behave as if the hook were present, but failed.  The reason
+# for this is that revision properties are UNVERSIONED, meaning that
+# a successful propchange is destructive;  the old value is gone
+# forever.  We recommend the hook back up the old value somewhere.
+#
+# On a Unix system, the normal procedure is to have 'pre-revprop-change'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'pre-revprop-change' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'pre-revprop-change.bat' or 'pre-revprop-change.exe',
+# but the basic idea is the same.
+#
+# The hook program typically does not inherit the environment of
+# its parent process.  For example, a common problem is for the
+# PATH environment variable to not be set to its usual value, so
+# that subprograms fail to launch unless invoked via absolute path.
+# If you're having unexpected problems with a hook program, the
+# culprit may be unusual (or missing) environment variables.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter.
+# For more examples and pre-written hooks, see those in
+# the Subversion repository at
+# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
+# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
+
+
+REPOS="$1"
+REV="$2"
+USER="$3"
+PROPNAME="$4"
+ACTION="$5"
+
+if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi
+
+echo "Changing revision properties other than svn:log is prohibited" >&2
+exit 1
Index: continuum-release2/src/test/scm/hooks/post-commit.tmpl
===================================================================
--- continuum-release2/src/test/scm/hooks/post-commit.tmpl	(revision 0)
+++ continuum-release2/src/test/scm/hooks/post-commit.tmpl	(revision 0)
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+# POST-COMMIT HOOK
+#
+# The post-commit hook is invoked after a commit.  Subversion runs
+# this hook by invoking a program (script, executable, binary, etc.)
+# named 'post-commit' (for which this file is a template) with the 
+# following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] REV          (the number of the revision just committed)
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# Because the commit has already completed and cannot be undone,
+# the exit code of the hook program is ignored.  The hook program
+# can use the 'svnlook' utility to help it examine the
+# newly-committed tree.
+#
+# On a Unix system, the normal procedure is to have 'post-commit'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'post-commit' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'post-commit.bat' or 'post-commit.exe',
+# but the basic idea is the same.
+# 
+# The hook program typically does not inherit the environment of
+# its parent process.  For example, a common problem is for the
+# PATH environment variable to not be set to its usual value, so
+# that subprograms fail to launch unless invoked via absolute path.
+# If you're having unexpected problems with a hook program, the
+# culprit may be unusual (or missing) environment variables.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter.
+# For more examples and pre-written hooks, see those in
+# the Subversion repository at
+# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
+# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
+
+
+REPOS="$1"
+REV="$2"
+
+commit-email.pl "$REPOS" "$REV" commit-watchers@example.org
+log-commit.py --repository "$REPOS" --revision "$REV"
Index: continuum-release2/src/test/scm/hooks/post-lock.tmpl
===================================================================
--- continuum-release2/src/test/scm/hooks/post-lock.tmpl	(revision 0)
+++ continuum-release2/src/test/scm/hooks/post-lock.tmpl	(revision 0)
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# POST-LOCK HOOK
+#
+# The post-lock hook is run after a path is locked.  Subversion runs
+# this hook by invoking a program (script, executable, binary, etc.)
+# named 'post-lock' (for which this file is a template) with the 
+# following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] USER         (the user who created the lock)
+#
+# The paths that were just locked are passed to the hook via STDIN (as
+# of Subversion 1.2, only one path is passed per invocation, but the
+# plan is to pass all locked paths at once, so the hook program
+# should be written accordingly).
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# Because the lock has already been created and cannot be undone,
+# the exit code of the hook program is ignored.  The hook program
+# can use the 'svnlook' utility to help it examine the
+# newly-created lock.
+#
+# On a Unix system, the normal procedure is to have 'post-lock'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'post-lock' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'post-lock.bat' or 'post-lock.exe',
+# but the basic idea is the same.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter:
+
+REPOS="$1"
+USER="$2"
+
+# Send email to interested parties, let them know a lock was created:
+mailer.py lock "$REPOS" "$USER" /path/to/mailer.conf
Index: continuum-release2/src/test/scm/hooks/pre-commit.tmpl
===================================================================
--- continuum-release2/src/test/scm/hooks/pre-commit.tmpl	(revision 0)
+++ continuum-release2/src/test/scm/hooks/pre-commit.tmpl	(revision 0)
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+# PRE-COMMIT HOOK
+#
+# The pre-commit hook is invoked before a Subversion txn is
+# committed.  Subversion runs this hook by invoking a program
+# (script, executable, binary, etc.) named 'pre-commit' (for which
+# this file is a template), with the following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] TXN-NAME     (the name of the txn about to be committed)
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# If the hook program exits with success, the txn is committed; but
+# if it exits with failure (non-zero), the txn is aborted, no commit
+# takes place, and STDERR is returned to the client.   The hook
+# program can use the 'svnlook' utility to help it examine the txn.
+#
+# On a Unix system, the normal procedure is to have 'pre-commit'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+#   ***  NOTE: THE HOOK PROGRAM MUST NOT MODIFY THE TXN, EXCEPT  ***
+#   ***  FOR REVISION PROPERTIES (like svn:log or svn:author).   ***
+#
+#   This is why we recommend using the read-only 'svnlook' utility.
+#   In the future, Subversion may enforce the rule that pre-commit
+#   hooks should not modify the versioned data in txns, or else come
+#   up with a mechanism to make it safe to do so (by informing the
+#   committing client of the changes).  However, right now neither
+#   mechanism is implemented, so hook writers just have to be careful.
+#
+# Note that 'pre-commit' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'pre-commit.bat' or 'pre-commit.exe',
+# but the basic idea is the same.
+#
+# The hook program typically does not inherit the environment of
+# its parent process.  For example, a common problem is for the
+# PATH environment variable to not be set to its usual value, so
+# that subprograms fail to launch unless invoked via absolute path.
+# If you're having unexpected problems with a hook program, the
+# culprit may be unusual (or missing) environment variables.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter.
+# For more examples and pre-written hooks, see those in
+# the Subversion repository at
+# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
+# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
+
+
+REPOS="$1"
+TXN="$2"
+
+# Make sure that the log message contains some text.
+SVNLOOK=/usr/bin/svnlook
+$SVNLOOK log -t "$TXN" "$REPOS" | \
+   grep "[a-zA-Z0-9]" > /dev/null || exit 1
+
+# Check that the author of this commit has the rights to perform
+# the commit on the files and directories being modified.
+commit-access-control.pl "$REPOS" "$TXN" commit-access-control.cfg || exit 1
+
+# All checks passed, so allow the commit.
+exit 0
Index: continuum-release2/src/test/scm/hooks/pre-lock.tmpl
===================================================================
--- continuum-release2/src/test/scm/hooks/pre-lock.tmpl	(revision 0)
+++ continuum-release2/src/test/scm/hooks/pre-lock.tmpl	(revision 0)
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+# PRE-LOCK HOOK
+#
+# The pre-lock hook is invoked before an exclusive lock is
+# created.  Subversion runs this hook by invoking a program 
+# (script, executable, binary, etc.) named 'pre-lock' (for which
+# this file is a template), with the following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] PATH         (the path in the repository about to be locked)
+#   [3] USER         (the user creating the lock)
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# If the hook program exits with success, the lock is created; but
+# if it exits with failure (non-zero), the lock action is aborted
+# and STDERR is returned to the client.
+
+# On a Unix system, the normal procedure is to have 'pre-lock'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'pre-lock' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'pre-lock.bat' or 'pre-lock.exe',
+# but the basic idea is the same.
+#
+# Here is an example hook script, for a Unix /bin/sh interpreter:
+
+REPOS="$1"
+PATH="$2"
+USER="$3"
+
+# If a lock exists and is owned by a different person, don't allow it
+# to be stolen (e.g., with 'svn lock --force ...').
+
+# (Maybe this script could send email to the lock owner?)
+SVNLOOK=/usr/bin/svnlook
+GREP=/bin/grep
+SED=/bin/sed
+
+LOCK_OWNER=`$SVNLOOK lock "$REPOS" "$PATH" | \
+            $GREP '^Owner: ' | $SED 's/Owner: //'`
+
+# If we get no result from svnlook, there's no lock, allow the lock to
+# happen:
+if [ "$LOCK_OWNER" = "" ]; then
+  exit 0
+fi
+
+# If the person locking matches the lock's owner, allow the lock to
+# happen:
+if [ "$LOCK_OWNER" = "$USER" ]; then
+  exit 0
+fi
+
+# Otherwise, we've got an owner mismatch, so return failure:
+echo "Error: $PATH already locked by ${LOCK_OWNER}." 1>&2
+exit 1
Index: continuum-release2/src/test/scm/hooks/post-unlock.tmpl
===================================================================
--- continuum-release2/src/test/scm/hooks/post-unlock.tmpl	(revision 0)
+++ continuum-release2/src/test/scm/hooks/post-unlock.tmpl	(revision 0)
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# POST-UNLOCK HOOK
+#
+# The post-unlock hook runs after a path is unlocked.  Subversion runs
+# this hook by invoking a program (script, executable, binary, etc.)
+# named 'post-unlock' (for which this file is a template) with the 
+# following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] USER         (the user who destroyed the lock)
+#
+# The paths that were just unlocked are passed to the hook via STDIN
+# (as of Subversion 1.2, only one path is passed per invocation, but
+# the plan is to pass all unlocked paths at once, so the hook program
+# should be written accordingly).
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# Because the lock has already been destroyed and cannot be undone,
+# the exit code of the hook program is ignored.
+#
+# On a Unix system, the normal procedure is to have 'post-unlock'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'post-unlock' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'post-unlock.bat' or 'post-unlock.exe',
+# but the basic idea is the same.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter:
+
+REPOS="$1"
+USER="$2"
+
+# Send email to interested parties, let them know a lock was removed:
+mailer.py unlock "$REPOS" "$USER" /path/to/mailer.conf
Index: continuum-release2/src/test/scm/hooks/pre-unlock.tmpl
===================================================================
--- continuum-release2/src/test/scm/hooks/pre-unlock.tmpl	(revision 0)
+++ continuum-release2/src/test/scm/hooks/pre-unlock.tmpl	(revision 0)
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+# PRE-UNLOCK HOOK
+#
+# The pre-unlock hook is invoked before an exclusive lock is
+# destroyed.  Subversion runs this hook by invoking a program 
+# (script, executable, binary, etc.) named 'pre-unlock' (for which
+# this file is a template), with the following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] PATH         (the path in the repository about to be unlocked)
+#   [3] USER         (the user destroying the lock)
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# If the hook program exits with success, the lock is destroyed; but
+# if it exits with failure (non-zero), the unlock action is aborted
+# and STDERR is returned to the client.
+
+# On a Unix system, the normal procedure is to have 'pre-unlock'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'pre-unlock' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'pre-unlock.bat' or 'pre-unlock.exe',
+# but the basic idea is the same.
+#
+# Here is an example hook script, for a Unix /bin/sh interpreter:
+
+REPOS="$1"
+PATH="$2"
+USER="$3"
+
+# If a lock is owned by a different person, don't allow it be broken.
+# (Maybe this script could send email to the lock owner?)
+
+SVNLOOK=/usr/bin/svnlook
+GREP=/bin/grep
+SED=/bin/sed
+
+LOCK_OWNER=`$SVNLOOK lock "$REPOS" "$PATH" | \
+            $GREP '^Owner: ' | $SED 's/Owner: //'`
+
+# If we get no result from svnlook, there's no lock, return success:
+if [ "$LOCK_OWNER" = "" ]; then
+  exit 0
+fi
+# If the person unlocking matches the lock's owner, return success:
+if [ "$LOCK_OWNER" = "$USER" ]; then
+  exit 0
+fi
+
+# Otherwise, we've got an owner mismatch, so return failure:
+echo "Error: $PATH locked by ${LOCK_OWNER}." 1>&2
+exit 1
Index: continuum-release2/src/test/scm/hooks/start-commit.tmpl
===================================================================
--- continuum-release2/src/test/scm/hooks/start-commit.tmpl	(revision 0)
+++ continuum-release2/src/test/scm/hooks/start-commit.tmpl	(revision 0)
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+# START-COMMIT HOOK
+#
+# The start-commit hook is invoked before a Subversion txn is created
+# in the process of doing a commit.  Subversion runs this hook
+# by invoking a program (script, executable, binary, etc.) named
+# 'start-commit' (for which this file is a template)
+# with the following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] USER         (the authenticated user attempting to commit)
+#
+# The default working directory for the invocation is undefined, so
+# the program should set one explicitly if it cares.
+#
+# If the hook program exits with success, the commit continues; but
+# if it exits with failure (non-zero), the commit is stopped before
+# a Subversion txn is created, and STDERR is returned to the client.
+#
+# On a Unix system, the normal procedure is to have 'start-commit'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'start-commit' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'start-commit.bat' or 'start-commit.exe',
+# but the basic idea is the same.
+# 
+# The hook program typically does not inherit the environment of
+# its parent process.  For example, a common problem is for the
+# PATH environment variable to not be set to its usual value, so
+# that subprograms fail to launch unless invoked via absolute path.
+# If you're having unexpected problems with a hook program, the
+# culprit may be unusual (or missing) environment variables.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter.
+# For more examples and pre-written hooks, see those in
+# the Subversion repository at
+# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
+# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
+
+
+REPOS="$1"
+USER="$2"
+
+commit-allower.pl --repository "$REPOS" --user "$USER" || exit 1
+special-auth-check.py --user "$USER" --auth-level 3 || exit 1
+
+# All checks passed, so allow the commit.
+exit 0
Index: continuum-release2/src/test/scm/hooks/post-revprop-change.tmpl
===================================================================
--- continuum-release2/src/test/scm/hooks/post-revprop-change.tmpl	(revision 0)
+++ continuum-release2/src/test/scm/hooks/post-revprop-change.tmpl	(revision 0)
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+# POST-REVPROP-CHANGE HOOK
+#
+# The post-revprop-change hook is invoked after a revision property
+# has been added, modified or deleted.  Subversion runs this hook by
+# invoking a program (script, executable, binary, etc.) named
+# 'post-revprop-change' (for which this file is a template), with the
+# following ordered arguments:
+#
+#   [1] REPOS-PATH   (the path to this repository)
+#   [2] REV          (the revision that was tweaked)
+#   [3] USER         (the username of the person tweaking the property)
+#   [4] PROPNAME     (the property that was changed)
+#   [5] ACTION       (the property was 'A'dded, 'M'odified, or 'D'eleted)
+#
+#   [STDIN] PROPVAL  ** the old property value is passed via STDIN.
+#
+# Because the propchange has already completed and cannot be undone,
+# the exit code of the hook program is ignored.  The hook program
+# can use the 'svnlook' utility to help it examine the
+# new property value.
+#
+# On a Unix system, the normal procedure is to have 'post-revprop-change'
+# invoke other programs to do the real work, though it may do the
+# work itself too.
+#
+# Note that 'post-revprop-change' must be executable by the user(s) who will
+# invoke it (typically the user httpd runs as), and that user must
+# have filesystem-level permission to access the repository.
+#
+# On a Windows system, you should name the hook program
+# 'post-revprop-change.bat' or 'post-revprop-change.exe',
+# but the basic idea is the same.
+# 
+# The hook program typically does not inherit the environment of
+# its parent process.  For example, a common problem is for the
+# PATH environment variable to not be set to its usual value, so
+# that subprograms fail to launch unless invoked via absolute path.
+# If you're having unexpected problems with a hook program, the
+# culprit may be unusual (or missing) environment variables.
+# 
+# Here is an example hook script, for a Unix /bin/sh interpreter.
+# For more examples and pre-written hooks, see those in
+# the Subversion repository at
+# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
+# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
+
+
+REPOS="$1"
+REV="$2"
+USER="$3"
+PROPNAME="$4"
+ACTION="$5"
+
+propchange-email.pl "$REPOS" "$REV" "$USER" "$PROPNAME" watchers@example.org
Index: continuum-release2/src/test/scm/conf/svnserve.conf
===================================================================
--- continuum-release2/src/test/scm/conf/svnserve.conf	(revision 0)
+++ continuum-release2/src/test/scm/conf/svnserve.conf	(revision 0)
@@ -0,0 +1,30 @@
+### This file controls the configuration of the svnserve daemon, if you
+### use it to allow access to this repository.  (If you only allow
+### access through http: and/or file: URLs, then this file is
+### irrelevant.)
+
+### Visit http://subversion.tigris.org/ for more information.
+
+[general]
+### These options control access to the repository for unauthenticated
+### and authenticated users.  Valid values are "write", "read",
+### and "none".  The sample settings below are the defaults.
+# anon-access = read
+# auth-access = write
+### The password-db option controls the location of the password
+### database file.  Unless you specify a path starting with a /,
+### the file's location is relative to the conf directory.
+### Uncomment the line below to use the default password file.
+# password-db = passwd
+### The authz-db option controls the location of the authorization
+### rules for path-based access control.  Unless you specify a path
+### starting with a /, the file's location is relative to the conf
+### directory.  If you don't specify an authz-db, no path-based access
+### control is done.
+### Uncomment the line below to use the default authorization file.
+# authz-db = authz
+### This option specifies the authentication realm of the repository.
+### If two repositories have the same authentication realm, they should
+### have the same password database, and vice versa.  The default realm
+### is repository's uuid.
+# realm = My First Repository
Index: continuum-release2/src/test/scm/conf/passwd
===================================================================
--- continuum-release2/src/test/scm/conf/passwd	(revision 0)
+++ continuum-release2/src/test/scm/conf/passwd	(revision 0)
@@ -0,0 +1,8 @@
+### This file is an example password file for svnserve.
+### Its format is similar to that of svnserve.conf. As shown in the
+### example below it contains one section labelled [users].
+### The name and password for each user follow, one account per line.
+
+[users]
+# harry = harryssecret
+# sally = sallyssecret
Index: continuum-release2/src/test/scm/conf/authz
===================================================================
--- continuum-release2/src/test/scm/conf/authz	(revision 0)
+++ continuum-release2/src/test/scm/conf/authz	(revision 0)
@@ -0,0 +1,21 @@
+### This file is an example authorization file for svnserve.
+### Its format is identical to that of mod_authz_svn authorization
+### files.
+### As shown below each section defines authorizations for the path and
+### (optional) repository specified by the section name.
+### The authorizations follow. An authorization line can refer to a
+### single user, to a group of users defined in a special [groups]
+### section, or to anyone using the '*' wildcard.  Each definition can
+### grant read ('r') access, read-write ('rw') access, or no access
+### ('').
+
+[groups]
+# harry_and_sally = harry,sally
+
+# [/foo/bar]
+# harry = rw
+# * =
+
+# [repository:/baz/fuz]
+# @harry_and_sally = rw
+# * = r
Index: continuum-release2/src/test/scm/db/revs/0
===================================================================
--- continuum-release2/src/test/scm/db/revs/0	(revision 0)
+++ continuum-release2/src/test/scm/db/revs/0	(revision 0)
@@ -0,0 +1,11 @@
+PLAIN
+END
+ENDREP
+id: 0.0.r0/17
+type: dir
+count: 0
+text: 0 0 4 4 2d2977d1c96f487abe4a1e202dd03b4e
+cpath: /
+
+
+17 107
Index: continuum-release2/src/test/scm/db/revs/1
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: continuum-release2/src/test/scm/db/revs/1
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: continuum-release2/src/test/scm/db/revs/10
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: continuum-release2/src/test/scm/db/revs/10
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: continuum-release2/src/test/scm/db/revs/2
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: continuum-release2/src/test/scm/db/revs/2
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: continuum-release2/src/test/scm/db/revs/3
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: continuum-release2/src/test/scm/db/revs/3
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: continuum-release2/src/test/scm/db/revs/4
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: continuum-release2/src/test/scm/db/revs/4
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: continuum-release2/src/test/scm/db/revs/5
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: continuum-release2/src/test/scm/db/revs/5
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: continuum-release2/src/test/scm/db/revs/6
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: continuum-release2/src/test/scm/db/revs/6
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: continuum-release2/src/test/scm/db/revs/7
===================================================================
--- continuum-release2/src/test/scm/db/revs/7	(revision 0)
+++ continuum-release2/src/test/scm/db/revs/7	(revision 0)
@@ -0,0 +1,60 @@
+id: 1j.0.r7/0
+type: dir
+count: 0
+cpath: /fromTag/branches
+copyroot: 0 /
+
+PLAIN
+K 8
+branches
+V 13
+dir 1j.0.r7/0
+K 4
+tags
+V 16
+dir 16.0.r5/3001
+K 5
+trunk
+V 15
+dir 17.0.r6/309
+END
+ENDREP
+id: 15.0.r7/184
+type: dir
+pred: 15.0.r6/532
+count: 2
+text: 7 73 98 98 377ae22be507d303996b6f957832c766
+cpath: /fromTag
+copyroot: 0 /
+
+PLAIN
+K 1
+A
+V 14
+dir 1.0.r2/916
+K 1
+B
+V 14
+dir f.0.r4/885
+K 7
+fromTag
+V 15
+dir 15.0.r7/184
+K 6
+simple
+V 14
+dir s.0.r3/894
+END
+ENDREP
+id: 0.0.r7/451
+type: dir
+pred: 0.0.r6/801
+count: 7
+text: 7 318 120 120 8e56fc892960208175f954018fb482e2
+cpath: /
+copyroot: 0 /
+
+_0.0.t6-1 add false false /fromTag/branches
+
+
+451 579
Index: continuum-release2/src/test/scm/db/revs/8
===================================================================
--- continuum-release2/src/test/scm/db/revs/8	(revision 0)
+++ continuum-release2/src/test/scm/db/revs/8	(revision 0)
@@ -0,0 +1,77 @@
+id: 17.1.r8/0
+type: dir
+pred: 17.0.r5/2876
+count: 1
+text: 5 2794 69 69 94a2fe162d91a99b39112d4baef5209e
+cpath: /fromTag/tags/nightly
+copyfrom: 5 /fromTag/trunk
+
+PLAIN
+K 7
+nightly
+V 13
+dir 17.1.r8/0
+END
+ENDREP
+id: 16.0.r8/209
+type: dir
+pred: 16.0.r5/3001
+count: 1
+text: 8 161 35 35 a7ed83758384125e5cce06b69e4e7ef6
+cpath: /fromTag/tags
+copyroot: 0 /
+
+PLAIN
+K 8
+branches
+V 13
+dir 1j.0.r7/0
+K 4
+tags
+V 15
+dir 16.0.r8/209
+K 5
+trunk
+V 15
+dir 17.0.r6/309
+END
+ENDREP
+id: 15.0.r8/460
+type: dir
+pred: 15.0.r7/184
+count: 3
+text: 8 350 97 97 3b621f0b0b5916f2965037b8b231439f
+cpath: /fromTag
+copyroot: 0 /
+
+PLAIN
+K 1
+A
+V 14
+dir 1.0.r2/916
+K 1
+B
+V 14
+dir f.0.r4/885
+K 7
+fromTag
+V 15
+dir 15.0.r8/460
+K 6
+simple
+V 14
+dir s.0.r3/894
+END
+ENDREP
+id: 0.0.r8/728
+type: dir
+pred: 0.0.r7/451
+count: 8
+text: 8 595 120 120 92b872d2b0e215b1193bba88ce8894ec
+cpath: /
+copyroot: 0 /
+
+17._0.t7-1 add false false /fromTag/tags/nightly
+5 /fromTag/trunk
+
+728 856
Index: continuum-release2/src/test/scm/db/revs/9
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: continuum-release2/src/test/scm/db/revs/9
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: continuum-release2/src/test/scm/db/revprops/0
===================================================================
--- continuum-release2/src/test/scm/db/revprops/0	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/0	(revision 0)
@@ -0,0 +1,5 @@
+K 8
+svn:date
+V 27
+2008-03-16T11:57:36.971828Z
+END
Index: continuum-release2/src/test/scm/db/revprops/1
===================================================================
--- continuum-release2/src/test/scm/db/revprops/1	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/1	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 8
+decherfb
+K 8
+svn:date
+V 27
+2008-03-16T12:03:45.089916Z
+K 7
+svn:log
+V 18
+initial repository
+END
Index: continuum-release2/src/test/scm/db/revprops/10
===================================================================
--- continuum-release2/src/test/scm/db/revprops/10	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/10	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 8
+decherfb
+K 8
+svn:date
+V 27
+2008-03-25T08:48:58.092362Z
+K 7
+svn:log
+V 21
+add test for rollback
+END
Index: continuum-release2/src/test/scm/db/revprops/2
===================================================================
--- continuum-release2/src/test/scm/db/revprops/2	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/2	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 8
+decherfb
+K 8
+svn:date
+V 27
+2008-03-16T16:01:50.940947Z
+K 7
+svn:log
+V 27
+add distribution management
+END
Index: continuum-release2/src/test/scm/db/revprops/3
===================================================================
--- continuum-release2/src/test/scm/db/revprops/3	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/3	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 8
+decherfb
+K 8
+svn:date
+V 27
+2008-03-16T16:05:30.794489Z
+K 7
+svn:log
+V 27
+add distribution management
+END
Index: continuum-release2/src/test/scm/db/revprops/4
===================================================================
--- continuum-release2/src/test/scm/db/revprops/4	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/4	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 8
+decherfb
+K 8
+svn:date
+V 27
+2008-03-16T16:05:37.138534Z
+K 7
+svn:log
+V 27
+add distribution management
+END
Index: continuum-release2/src/test/scm/db/revprops/5
===================================================================
--- continuum-release2/src/test/scm/db/revprops/5	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/5	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 8
+decherfb
+K 8
+svn:date
+V 27
+2008-03-16T16:53:35.168487Z
+K 7
+svn:log
+V 11
+add project
+END
Index: continuum-release2/src/test/scm/db/revprops/6
===================================================================
--- continuum-release2/src/test/scm/db/revprops/6	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/6	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 8
+decherfb
+K 8
+svn:date
+V 27
+2008-03-16T16:55:30.416529Z
+K 7
+svn:log
+V 46
+add file that should not appear in the release
+END
Index: continuum-release2/src/test/scm/db/revprops/7
===================================================================
--- continuum-release2/src/test/scm/db/revprops/7	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/7	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 8
+decherfb
+K 8
+svn:date
+V 27
+2008-03-16T17:09:16.686750Z
+K 7
+svn:log
+V 22
+add branches structure
+END
Index: continuum-release2/src/test/scm/db/revprops/8
===================================================================
--- continuum-release2/src/test/scm/db/revprops/8	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/8	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 8
+decherfb
+K 8
+svn:date
+V 27
+2008-03-16T17:36:29.042777Z
+K 7
+svn:log
+V 14
+add nightlytag
+END
Index: continuum-release2/src/test/scm/db/revprops/9
===================================================================
--- continuum-release2/src/test/scm/db/revprops/9	(revision 0)
+++ continuum-release2/src/test/scm/db/revprops/9	(revision 0)
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 8
+decherfb
+K 8
+svn:date
+V 27
+2008-03-16T17:40:34.609031Z
+K 7
+svn:log
+V 47
+add distribution management for fromTag project
+END
Index: continuum-release2/src/test/scm/db/write-lock
===================================================================
Index: continuum-release2/src/test/scm/db/current
===================================================================
--- continuum-release2/src/test/scm/db/current	(revision 0)
+++ continuum-release2/src/test/scm/db/current	(revision 0)
@@ -0,0 +1 @@
+10 1x 2
Index: continuum-release2/src/test/scm/db/uuid
===================================================================
--- continuum-release2/src/test/scm/db/uuid	(revision 0)
+++ continuum-release2/src/test/scm/db/uuid	(revision 0)
@@ -0,0 +1 @@
+2ec2f1d9-015c-468c-bc81-9ec87136bbb5
Index: continuum-release2/src/test/scm/db/fs-type
===================================================================
--- continuum-release2/src/test/scm/db/fs-type	(revision 0)
+++ continuum-release2/src/test/scm/db/fs-type	(revision 0)
@@ -0,0 +1 @@
+fsfs
Index: continuum-release2/src/test/scm/db/transactions/10-1.txn/node.0.0
===================================================================
--- continuum-release2/src/test/scm/db/transactions/10-1.txn/node.0.0	(revision 0)
+++ continuum-release2/src/test/scm/db/transactions/10-1.txn/node.0.0	(revision 0)
@@ -0,0 +1,8 @@
+id: 0.0.t10-1
+type: dir
+pred: 0.0.r10/3818
+count: 11
+text: 10 3643 162 162 c2891e7be8be1e47a4ed575f3d9ed24c
+cpath: /
+copyroot: 0 /
+
Index: continuum-release2/src/test/scm/db/transactions/10-1.txn/rev-lock
===================================================================
Index: continuum-release2/src/test/scm/db/transactions/10-1.txn/props
===================================================================
--- continuum-release2/src/test/scm/db/transactions/10-1.txn/props	(revision 0)
+++ continuum-release2/src/test/scm/db/transactions/10-1.txn/props	(revision 0)
@@ -0,0 +1,17 @@
+K 10
+svn:author
+V 8
+decherfb
+K 15
+svn:check-locks
+V 4
+true
+K 8
+svn:date
+V 27
+2008-03-27T09:38:58.082260Z
+K 7
+svn:log
+V 32
+[maven-scm] copy for branch test
+END
Index: continuum-release2/src/test/scm/db/transactions/10-1.txn/changes
===================================================================
Index: continuum-release2/src/test/scm/db/transactions/10-1.txn/next-ids
===================================================================
--- continuum-release2/src/test/scm/db/transactions/10-1.txn/next-ids	(revision 0)
+++ continuum-release2/src/test/scm/db/transactions/10-1.txn/next-ids	(revision 0)
@@ -0,0 +1 @@
+0 0
Index: continuum-release2/src/test/scm/db/transactions/10-1.txn/rev
===================================================================
Index: continuum-release2/src/test/scm/db/transactions/10-2.txn/node.0.0
===================================================================
--- continuum-release2/src/test/scm/db/transactions/10-2.txn/node.0.0	(revision 0)
+++ continuum-release2/src/test/scm/db/transactions/10-2.txn/node.0.0	(revision 0)
@@ -0,0 +1,8 @@
+id: 0.0.t10-2
+type: dir
+pred: 0.0.r10/3818
+count: 11
+text: 10 3643 162 162 c2891e7be8be1e47a4ed575f3d9ed24c
+cpath: /
+copyroot: 0 /
+
Index: continuum-release2/src/test/scm/db/transactions/10-2.txn/rev-lock
===================================================================
Index: continuum-release2/src/test/scm/db/transactions/10-2.txn/props
===================================================================
--- continuum-release2/src/test/scm/db/transactions/10-2.txn/props	(revision 0)
+++ continuum-release2/src/test/scm/db/transactions/10-2.txn/props	(revision 0)
@@ -0,0 +1,17 @@
+K 10
+svn:author
+V 8
+decherfb
+K 15
+svn:check-locks
+V 4
+true
+K 8
+svn:date
+V 27
+2008-03-27T09:39:14.032309Z
+K 7
+svn:log
+V 32
+[maven-scm] copy for branch test
+END
Index: continuum-release2/src/test/scm/db/transactions/10-2.txn/changes
===================================================================
Index: continuum-release2/src/test/scm/db/transactions/10-2.txn/next-ids
===================================================================
--- continuum-release2/src/test/scm/db/transactions/10-2.txn/next-ids	(revision 0)
+++ continuum-release2/src/test/scm/db/transactions/10-2.txn/next-ids	(revision 0)
@@ -0,0 +1 @@
+0 0
Index: continuum-release2/src/test/scm/db/transactions/10-2.txn/rev
===================================================================
Index: continuum-release2/src/test/scm/db/transactions/readme.txt
===================================================================
--- continuum-release2/src/test/scm/db/transactions/readme.txt	(revision 0)
+++ continuum-release2/src/test/scm/db/transactions/readme.txt	(revision 0)
@@ -0,0 +1 @@
+this file is here so that the resources plugin will copy this directory. It doesn't copy empty directories.
Index: continuum-release2/src/test/scm/db/format
===================================================================
--- continuum-release2/src/test/scm/db/format	(revision 0)
+++ continuum-release2/src/test/scm/db/format	(revision 0)
@@ -0,0 +1 @@
+2
Index: continuum-release2/src/test/scm/format
===================================================================
--- continuum-release2/src/test/scm/format	(revision 0)
+++ continuum-release2/src/test/scm/format	(revision 0)
@@ -0,0 +1 @@
+5
Index: continuum-release2/src/test/scm/locks/db.lock
===================================================================
--- continuum-release2/src/test/scm/locks/db.lock	(revision 0)
+++ continuum-release2/src/test/scm/locks/db.lock	(revision 0)
@@ -0,0 +1,3 @@
+This file is not used by Subversion 1.3.x or later.
+However, its existence is required for compatibility with
+Subversion 1.2.x or earlier.
Index: continuum-release2/src/test/scm/locks/db-logs.lock
===================================================================
--- continuum-release2/src/test/scm/locks/db-logs.lock	(revision 0)
+++ continuum-release2/src/test/scm/locks/db-logs.lock	(revision 0)
@@ -0,0 +1,3 @@
+This file is not used by Subversion 1.3.x or later.
+However, its existence is required for compatibility with
+Subversion 1.2.x or earlier.
Index: continuum-release2/src/test/scm/README.txt
===================================================================
--- continuum-release2/src/test/scm/README.txt	(revision 0)
+++ continuum-release2/src/test/scm/README.txt	(revision 0)
@@ -0,0 +1,5 @@
+This is a Subversion repository; use the 'svnadmin' tool to examine
+it.  Do not add, delete, or modify files here unless you know how
+to avoid corrupting the repository.
+
+Visit http://subversion.tigris.org/ for more information.
Index: continuum-release2/src/test/resources/application.xml
===================================================================
--- continuum-release2/src/test/resources/application.xml	(revision 0)
+++ continuum-release2/src/test/resources/application.xml	(revision 0)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  ~ 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.
+  -->
+<plexus>
+  <load-on-start>
+    <component>
+      <role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
+      <role-hint>release2</role-hint>
+    </component>
+  </load-on-start>
+</plexus>
Index: continuum-release2/src/test/resources/log4j.xml
===================================================================
--- continuum-release2/src/test/resources/log4j.xml	(revision 0)
+++ continuum-release2/src/test/resources/log4j.xml	(revision 0)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
+
+
+  <appender name="console" class="org.apache.log4j.ConsoleAppender">
+    <param name="Target" value="System.out"/>
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%d [%t] %-5p %c %x - %m%n"/>
+    </layout>
+  </appender>
+  
+  <root>
+    <priority value="debug" />
+    <appender-ref ref="console" />
+  </root>
+
+</log4j:configuration>
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/ProjectReleaseManager.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/ProjectReleaseManager.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/ProjectReleaseManager.java	(revision 0)
@@ -0,0 +1,13 @@
+package org.apache.maven.continuum.release;
+
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor;
+import org.codehaus.plexus.taskqueue.TaskQueueException;
+
+public interface ProjectReleaseManager {
+	/**
+	 * Create and execute the ReleaseProjectTask
+	 * @param projects
+	 * @return the releaseId.
+	 */
+	public String releaseProjects(ReleaseDescriptor releaseDescriptor) throws TaskQueueException;
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/task/ReleaseTask.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/task/ReleaseTask.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/task/ReleaseTask.java	(revision 0)
@@ -0,0 +1,21 @@
+package org.apache.maven.continuum.release.task;
+
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor;
+import org.codehaus.plexus.taskqueue.Task;
+
+public class ReleaseTask implements Task{
+	ReleaseDescriptor releaseDescriptor;
+	
+	@Override
+	public long getMaxExecutionTime() {
+		return 0;
+	}
+	
+	public ReleaseTask(ReleaseDescriptor releaseDescriptor) {
+		this.releaseDescriptor = releaseDescriptor;
+	}
+
+	public ReleaseDescriptor getReleaseDescriptor() {
+		return releaseDescriptor;
+	}
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/task/ReleaseProjectTask.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/task/ReleaseProjectTask.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/task/ReleaseProjectTask.java	(revision 0)
@@ -0,0 +1,71 @@
+package org.apache.maven.continuum.release.task;
+
+import org.apache.maven.continuum.release.bean.ReleaseProject;
+import org.codehaus.plexus.taskqueue.Task;
+
+public class ReleaseProjectTask implements Task{
+	ReleaseProject releaseProject;
+	String username;
+	String password;
+	boolean prepareRelease;
+	boolean performRelease;
+	
+	
+	public ReleaseProjectTask(ReleaseProject releaseProject, String username, String password, boolean prepareRelease, boolean performRelease) {
+		this.releaseProject = releaseProject;
+		this.username = username;
+		this.password = password;
+		this.prepareRelease = prepareRelease;
+		this.performRelease = performRelease;
+	}
+	
+	
+	public boolean isPrepareRelease() {
+		return prepareRelease;
+	}
+
+	public void setPrepareRelease(boolean prepareRelease) {
+		this.prepareRelease = prepareRelease;
+	}
+
+	public boolean isPerformRelease() {
+		return performRelease;
+	}
+
+	public void setPerformRelease(boolean performRelease) {
+		this.performRelease = performRelease;
+	}
+
+	public void setReleaseProject(ReleaseProject releaseProject) {
+		this.releaseProject = releaseProject;
+	}
+
+	@Override
+	public long getMaxExecutionTime() {
+		return 0;
+	}
+
+	public ReleaseProject getReleaseProject() {
+		return releaseProject;
+	}
+
+
+	public String getUsername() {
+		return username;
+	}
+
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+
+	public String getPassword() {
+		return password;
+	}
+
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/bean/ReleaseDescriptor.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/bean/ReleaseDescriptor.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/bean/ReleaseDescriptor.java	(revision 0)
@@ -0,0 +1,215 @@
+package org.apache.maven.continuum.release.bean;
+
+import java.io.File;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.continuum.model.system.Profile;
+
+public class ReleaseDescriptor {
+	public static enum Status {
+		CHECKOUT_SUCCESS,
+		PREPARE_STARTED,
+		PREPARE_SUCCESS,
+		PERFORM_STARTED,
+		PERFORM_SUCCESS,
+		CHECKOUT_FAILED,
+		PREPARE_FAILED,
+		ROLLBACK_STARTED,
+		ROLLBACK_SUCCESS,
+		ROLLBACK_FAILED,
+		PERFORM_FAILED, 
+		DEPENDENCY_FAILED,
+		DEPENDENCY_MISSING,
+		INVALID_POM,
+		ABORTED
+	}
+	
+	String releaseId;
+	String fromVersion;
+	String versionType;
+	String branchName;
+	String releaseTag; 
+	String releaseTagBase; //Use for svn.
+	String releaseVersion;
+	String nextDevelopmentVersion;
+
+	String username;
+	String password;
+	
+	Profile profile;
+	List<ReleaseProject> projectsToRelease;
+	
+	boolean prepareRelease = true;
+	boolean performRelease = true;
+	Set<ReleaseDependency> snapshotDependencies;
+	/**
+	 * where the release directory will be create.
+	 */
+	String buildDirectory;
+	
+	/**
+	 * Pointer to the release directory.
+	 */
+	File workingDirectory; 
+
+	public boolean isReleaseFinished() {
+		boolean finished = true;
+		for(ReleaseProject project : getProjectsToRelease()) {
+			if(project.getStatus()==null) {
+				finished = false;
+				break;
+			}
+			if(project.getStatus().compareTo(Status.CHECKOUT_FAILED)<0) {//if ">", project release is finished.
+				if(prepareRelease && project.getStatus().compareTo(Status.PREPARE_SUCCESS)<0 || 
+						performRelease && project.getStatus().compareTo(Status.PERFORM_SUCCESS)<0) {
+					finished = false;
+					break;
+				}
+			}
+		}
+		return finished;
+	}
+	
+	/**
+	 * 
+	 * @param artifactId
+	 * @return
+	 */
+	public ReleaseProject getReleaseProjectForArtifact(String artifactId) {
+		for(ReleaseProject project : getProjectsToRelease()) {
+			if(project.getProject().getArtifactId().equals(artifactId))
+				return project;
+		}
+		return null;
+	}
+	public ReleaseDependency getMissingSnapshotDependency(String groupId, String artifactId) {
+		if(getSnapshotDependencies() == null)
+			return null;
+		for(ReleaseDependency dep : getSnapshotDependencies()) {
+			if(dep.getArtifactId().equals(artifactId) && dep.getGroupId().equals(groupId))
+				return dep;
+		}
+		return null;
+	}
+	
+	public String getReleaseId() {
+		return releaseId;
+	}
+	public void setReleaseId(String releaseId) {
+		this.releaseId = releaseId;
+	}
+	public List<ReleaseProject> getProjectsToRelease() {
+		return projectsToRelease;
+	}
+	public void setProjectsToRelease(List<ReleaseProject> projectsToRelease) {
+		this.projectsToRelease = projectsToRelease;
+	}
+	
+	public Status getProjectsStatus(String artifactId) {
+		for(ReleaseProject p : projectsToRelease) {
+			if(p.getProject().getArtifactId().equals(artifactId))
+				return p.getStatus();
+		}
+		return null;
+	}
+
+	public Profile getProfile() {
+		return profile;
+	}
+	public void setProfile(Profile profile) {
+		this.profile = profile;
+	}
+	public boolean isPrepareRelease() {
+		return prepareRelease;
+	}
+	public void setPrepareRelease(boolean isPrepareRelease) {
+		this.prepareRelease = isPrepareRelease;
+	}
+	public boolean isPerformRelease() {
+		return performRelease;
+	}
+	public void setPerformRelease(boolean isPerformRelease) {
+		this.performRelease = isPerformRelease;
+	}
+	public String getFromVersion() {
+		return fromVersion;
+	}
+	public void setFromVersion(String fromVersion) {
+		this.fromVersion = fromVersion;
+	}
+	public String getVersionType() {
+		return versionType;
+	}
+	public void setVersionType(String versionType) {
+		this.versionType = versionType;
+	}
+	public String getBranchName() {
+		return branchName;
+	}
+	public void setBranchName(String branchName) {
+		this.branchName = branchName;
+	}
+	public String getUsername() {
+		return username;
+	}
+	public void setUsername(String username) {
+		this.username = username;
+	}
+	public String getPassword() {
+		return password;
+	}
+	public void setPassword(String password) {
+		this.password = password;
+	}
+	public String getReleaseTag() {
+		return releaseTag;
+	}
+	public void setReleaseTag(String releaseTag) {
+		this.releaseTag = releaseTag;
+	}
+	public String getReleaseVersion() {
+		return releaseVersion;
+	}
+	public void setReleaseVersion(String releaseVersion) {
+		this.releaseVersion = releaseVersion;
+	}
+	public String getNextDevelopmentVersion() {
+		return nextDevelopmentVersion;
+	}
+	public void setNextDevelopmentVersion(String nextDevelopmentVersion) {
+		this.nextDevelopmentVersion = nextDevelopmentVersion;
+	}
+
+	public String getReleaseTagBase() {
+		return releaseTagBase;
+	}
+
+	public void setReleaseTagBase(String releaseTagBase) {
+		this.releaseTagBase = releaseTagBase;
+	}
+	
+	public String getBuildDirectory() {
+		return buildDirectory;
+	}
+
+	public void setBuildDirectory(String buildDirectory) {
+		this.buildDirectory = buildDirectory;
+	}
+
+	public File getWorkingDirectory() {
+		return workingDirectory;
+	}
+
+	public void setWorkingDirectory(File workingDirectory) {
+		this.workingDirectory = workingDirectory;
+	}
+
+	public Set<ReleaseDependency> getSnapshotDependencies() {
+		return snapshotDependencies;
+	}
+
+	public void setSnapshotDependencies(Set<ReleaseDependency> snapshotDependencies) {
+		this.snapshotDependencies = snapshotDependencies;
+	}
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/bean/ReleaseDependency.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/bean/ReleaseDependency.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/bean/ReleaseDependency.java	(revision 0)
@@ -0,0 +1,72 @@
+package org.apache.maven.continuum.release.bean;
+
+public class ReleaseDependency {
+	String groupId;
+	String artifactId;
+	String releaseVersion;
+	String nextDevVersion;
+	public ReleaseDependency(String groupId, String artifactId,
+			String releaseVersion, String nextDevVersion) {
+		super();
+		this.groupId = groupId;
+		this.artifactId = artifactId;
+		this.releaseVersion = releaseVersion;
+		this.nextDevVersion = nextDevVersion;
+	}
+	public String getGroupId() {
+		return groupId;
+	}
+	public void setGroupId(String groupId) {
+		this.groupId = groupId;
+	}
+	public String getArtifactId() {
+		return artifactId;
+	}
+	public void setArtifactId(String artifactId) {
+		this.artifactId = artifactId;
+	}
+	public String getReleaseVersion() {
+		return releaseVersion;
+	}
+	public void setReleaseVersion(String releaseVersion) {
+		this.releaseVersion = releaseVersion;
+	}
+	public String getNextDevVersion() {
+		return nextDevVersion;
+	}
+	public void setNextDevVersion(String nextDevVersion) {
+		this.nextDevVersion = nextDevVersion;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((artifactId == null) ? 0 : artifactId.hashCode());
+		result = prime * result + ((groupId == null) ? 0 : groupId.hashCode());
+		return result;
+	}
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		final ReleaseDependency other = (ReleaseDependency) obj;
+		if (artifactId == null) {
+			if (other.artifactId != null)
+				return false;
+		} else if (!artifactId.equals(other.artifactId))
+			return false;
+		if (groupId == null) {
+			if (other.groupId != null)
+				return false;
+		} else if (!groupId.equals(other.groupId))
+			return false;
+		return true;
+	}
+	
+	
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/bean/ReleaseProject.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/bean/ReleaseProject.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/bean/ReleaseProject.java	(revision 0)
@@ -0,0 +1,175 @@
+package org.apache.maven.continuum.release.bean;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.Map;
+
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.model.system.Profile;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor.Status;
+import org.apache.maven.scm.repository.ScmRepository;
+import org.codehaus.plexus.util.cli.StreamConsumer;
+
+public class ReleaseProject {
+	String fromVersion;
+	String versionType;
+	String branchName;
+	String releaseTag;
+	String releaseTagBase;
+	String releaseVersion;
+	String nextDevelopmentVersion;
+	
+	Project project;
+	Profile profile;
+	Map<String, ReleaseDependency> dependencies;
+	
+	Status status;
+	
+	ScmRepository scmRepository;
+	File projectDirectory;
+	File outputLog;
+	PrintWriter pwOutputLog;
+	
+	StreamConsumer streamConsumer;
+	
+	public Status getStatus() {
+		return status;
+	}
+
+	public void setStatus(Status status) {
+		this.status = status;
+	}
+
+	public String getVersionType() {
+		return versionType;
+	}
+
+	public void setVersionType(String versionType) {
+		this.versionType = versionType;
+	}
+
+	public String getFromVersion() {
+		return fromVersion;
+	}
+
+	public String getReleaseTag() {
+		return releaseTag;
+	}
+
+	public String getReleaseVersion() {
+		return releaseVersion;
+	}
+
+	public String getNextDevelopmentVersion() {
+		return nextDevelopmentVersion;
+	}
+
+	public Project getProject() {
+		return project;
+	}
+
+	public String getBranchName() {
+		return branchName;
+	}
+
+	public void setFromVersion(String fromVersion) {
+		this.fromVersion = fromVersion;
+	}
+
+	public void setBranchName(String branchName) {
+		this.branchName = branchName;
+	}
+
+	public void setReleaseTag(String releaseTag) {
+		this.releaseTag = releaseTag;
+	}
+
+	public void setReleaseVersion(String releaseVersion) {
+		this.releaseVersion = releaseVersion;
+	}
+
+	public void setNextDevelopmentVersion(String nextDevelopmentVersion) {
+		this.nextDevelopmentVersion = nextDevelopmentVersion;
+	}
+
+	public void setProject(Project project) {
+		this.project = project;
+	}
+
+	public StreamConsumer getStreamConsumer() {
+		return streamConsumer;
+	}
+
+	public void setStreamConsumer(StreamConsumer streamConsumer) {
+		this.streamConsumer = streamConsumer;
+	}
+
+	public String getReleaseTagBase() {
+		return releaseTagBase;
+	}
+
+	public void setReleaseTagBase(String releaseTagBase) {
+		this.releaseTagBase = releaseTagBase;
+	}
+
+	public ScmRepository getScmRepository() {
+		return scmRepository;
+	}
+
+	public void setScmRepository(ScmRepository scmRepository) {
+		this.scmRepository = scmRepository;
+	}
+
+	public File getProjectDirectory() {
+		return projectDirectory;
+	}
+
+	public void setProjectDirectory(File projectDirectory) {
+		this.projectDirectory = projectDirectory;
+	}
+
+	public File getOutputLog() {
+		return outputLog;
+	}
+
+	public void setOutputLog(File outputLog) {
+		this.outputLog = outputLog;
+	}
+
+	public Profile getProfile() {
+		return profile;
+	}
+
+	public void setProfile(Profile profile) {
+		this.profile = profile;
+	}
+
+	public Map<String, ReleaseDependency> getDependencies() {
+		return dependencies;
+	}
+
+	public void setDependencies(Map<String, ReleaseDependency> dependencies) {
+		this.dependencies = dependencies;
+	}
+	public PrintWriter getPWOutputLog() throws FileNotFoundException {
+        if(!getOutputLog().getParentFile().exists())
+            getOutputLog().getParentFile().mkdirs();
+	    if(pwOutputLog == null)
+	        pwOutputLog = new PrintWriter(getOutputLog());
+	    return pwOutputLog;
+	    
+	}
+	
+	
+	public void writeResultMessage(String message, Exception exception) {
+		try {
+			getPWOutputLog().println(message);
+			if(exception != null)
+				exception.printStackTrace(getPWOutputLog());
+			getPWOutputLog().flush();
+		} catch(Exception e) {
+			e.printStackTrace();
+		}
+	}
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/DefaultProjectReleaseManager.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/DefaultProjectReleaseManager.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/DefaultProjectReleaseManager.java	(revision 0)
@@ -0,0 +1,124 @@
+package org.apache.maven.continuum.release;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+
+import org.apache.log4j.Logger;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor;
+import org.apache.maven.continuum.release.bean.ReleaseProject;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor.Status;
+import org.apache.maven.continuum.release.task.ReleaseTask;
+import org.apache.maven.scm.manager.NoSuchScmProviderException;
+import org.apache.maven.scm.manager.ScmManager;
+import org.apache.maven.scm.repository.ScmRepository;
+import org.apache.maven.scm.repository.ScmRepositoryException;
+import org.codehaus.plexus.taskqueue.TaskQueue;
+import org.codehaus.plexus.taskqueue.TaskQueueException;
+import org.codehaus.plexus.util.cli.WriterStreamConsumer;
+
+public class DefaultProjectReleaseManager implements ProjectReleaseManager{
+	Logger logger = Logger.getLogger(DefaultProjectReleaseManager.class);
+    
+	private TaskQueue releaseQueue;
+	private ScmManager scmManager;
+
+	/**
+	 * 
+	 */
+	public String releaseProjects(ReleaseDescriptor releaseDescriptor) throws TaskQueueException {
+		String releaseId = createReleaseId();
+		releaseDescriptor.setReleaseId(releaseId);
+		try {
+			prepareDescriptor(releaseDescriptor);
+			logger.info("Addind release to releaseQueue");
+			releaseQueue.put(
+					new ReleaseTask(releaseDescriptor));
+		} catch (Exception e) {
+			logger.error("Can't execute release: ", e);
+			for(ReleaseProject p : releaseDescriptor.getProjectsToRelease()) {
+				p.setStatus(Status.CHECKOUT_FAILED);
+			}
+			
+		}
+		
+		return releaseId;
+	}
+	
+	/**
+	 * Create a unique releaseId based on the timestamp.
+	 * @return
+	 */
+	private String createReleaseId() {
+		return String.valueOf(System.currentTimeMillis());
+	}
+	
+	/**
+	 * set all default values from ReleaseDescritptor on ReleaseProject objects. 
+	 * 
+	 * @param descriptor
+	 * @throws NoSuchScmProviderException 
+	 * @throws ScmRepositoryException 
+	 * @throws FileNotFoundException 
+	 */
+	private void prepareDescriptor(ReleaseDescriptor descriptor) throws ScmRepositoryException, NoSuchScmProviderException, FileNotFoundException {
+		descriptor.setWorkingDirectory(new File(descriptor.getBuildDirectory(), descriptor.getReleaseId()));
+		if(!descriptor.getWorkingDirectory().exists())
+			descriptor.getWorkingDirectory().mkdirs();
+		for (ReleaseProject p : descriptor.getProjectsToRelease()) {
+			if(!isEmpty(descriptor.getReleaseVersion()) && isEmpty(p.getReleaseVersion())) {
+				p.setReleaseVersion(descriptor.getReleaseVersion());
+			}
+			if(!isEmpty(descriptor.getBranchName()) && isEmpty(p.getBranchName())) {
+				p.setBranchName(replaceVariables(descriptor.getBranchName(), p));
+			} else if(!isEmpty(p.getBranchName()))
+				p.setBranchName(replaceVariables(p.getBranchName(), p));
+			
+			if(!isEmpty(descriptor.getFromVersion()) && isEmpty(p.getFromVersion()))
+				p.setFromVersion(replaceVariables(descriptor.getFromVersion(),p));
+			else if(!isEmpty(p.getFromVersion()))
+				p.setFromVersion(replaceVariables(p.getFromVersion(),p));
+			
+			if(!isEmpty(descriptor.getNextDevelopmentVersion()) && isEmpty(p.getNextDevelopmentVersion()))
+				p.setNextDevelopmentVersion(descriptor.getNextDevelopmentVersion());
+			if(!isEmpty(descriptor.getReleaseTag()) && isEmpty(p.getReleaseTag()))
+				p.setReleaseTag(replaceVariables(descriptor.getReleaseTag(), p));
+			else if (!isEmpty(p.getReleaseTag()))
+				p.setReleaseTag(replaceVariables(p.getReleaseTag(), p));
+				
+			if(!isEmpty(descriptor.getReleaseTagBase()) && isEmpty(p.getReleaseTagBase()))
+				p.setReleaseTagBase(descriptor.getReleaseTagBase());
+			
+			if(!isEmpty(descriptor.getVersionType()) && isEmpty(p.getVersionType()))
+				p.setVersionType(descriptor.getVersionType());
+			p.setScmRepository(getScmRepository(p, descriptor.getUsername(), descriptor.getPassword()));
+			p.setProjectDirectory(new File(descriptor.getWorkingDirectory(), p.getProject().getArtifactId()));
+			p.setOutputLog(new File(descriptor.getWorkingDirectory(), p.getProject().getArtifactId() + ".log"));
+			p.setStreamConsumer(new WriterStreamConsumer(p.getPWOutputLog()));
+			p.setProfile(descriptor.getProfile());
+		}
+	}
+	
+	String replaceVariables(String str, ReleaseProject project) {
+		if(str==null)
+			return null;
+		String version = project.getReleaseVersion();
+		str = str.replace("${project.artifactId}", project.getProject().getArtifactId())
+			.replace("${project.groupId}", project.getProject().getGroupId());
+		if(version != null)
+			str = str.replace("${project.version}", version).replaceAll("\\.", "-");
+		return str;
+	}
+	
+	private boolean isEmpty(String value) {
+		return (value == null) || value.equals("");
+	}
+	
+	private ScmRepository getScmRepository(ReleaseProject project, String username, String password) throws ScmRepositoryException, NoSuchScmProviderException {
+		ScmRepository scmRepository = scmManager.makeScmRepository(project.getProject().getScmUrl());
+		scmRepository.getProviderRepository().setUser(username);
+		scmRepository.getProviderRepository().setPassword(password);
+		scmRepository.getProviderRepository().setPersistCheckout(true);
+		return scmRepository;
+	}
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/maven2/MavenBuildExecutor.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/maven2/MavenBuildExecutor.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/maven2/MavenBuildExecutor.java	(revision 0)
@@ -0,0 +1,81 @@
+package org.apache.maven.continuum.release.maven2;
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.continuum.model.system.Installation;
+import org.apache.maven.continuum.model.system.Profile;
+import org.apache.maven.continuum.release.bean.ReleaseProject;
+import org.codehaus.plexus.logging.LogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.cli.CommandLineException;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+
+public class MavenBuildExecutor implements BuildExecutor, LogEnabled{
+	Logger logger;
+	
+	public void enableLogging(Logger arg0) {
+		logger = arg0;
+	}
+	
+	Commandline getCommandLine(Profile profile) {
+		Commandline cmdLine = new Commandline();
+		//get maven installation home.
+		String executable = "mvn";
+		if(profile != null) {
+			if(profile.getBuilder()!=null) {
+				String m2Home = profile.getBuilder().getVarValue();
+				if(m2Home!=null && !m2Home.equals(""))
+					executable = m2Home + File.separator + "bin" + File.separator + "mvn";
+			}
+			for(Installation inst : ((List<Installation>)profile.getEnvironmentVariables()))
+				cmdLine.addEnvironment(inst.getVarName(), inst.getVarValue());
+			
+			if(profile.getJdk() != null) {
+				String javaHome = profile.getJdk().getVarValue();
+		        cmdLine.addEnvironment( "JAVA_HOME", javaHome );
+			}
+		}
+		cmdLine.setExecutable(executable);
+		
+		cmdLine.addArguments(new String[] {
+				"--batch-mode"
+			});
+
+		return cmdLine;
+	}
+	
+	int execute(ReleaseProject project, String goal) {
+		Commandline cmdLine = getCommandLine(project.getProfile());
+		cmdLine.setWorkingDirectory(project.getProjectDirectory());
+		cmdLine.addArguments(new String[] {goal});
+		int result = -1;
+		try {
+			result = CommandLineUtils.executeCommandLine(cmdLine, project.getStreamConsumer(), project.getStreamConsumer());
+		} catch (CommandLineException e) {
+			logger.error(cmdLine.toString() + " fails: " + e.getMessage(), e);
+		} finally {
+			if(result != 0) {
+				logger.error(cmdLine.toString() + " fails: ");
+			}
+		}
+		return result;
+	}
+
+	public int perform(ReleaseProject project) {
+		return execute(project, "release:perform");
+	}
+	
+	public int prepare(ReleaseProject project) {
+		return execute(project, "release:prepare");
+	}
+	
+	public int rollback(ReleaseProject project) {
+		return execute(project, "release:rollback");
+	}
+	
+	public int check(ReleaseProject project) {
+		return execute(project, "dependency:resolve");
+	}
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/maven2/BuildExecutor.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/maven2/BuildExecutor.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/maven2/BuildExecutor.java	(revision 0)
@@ -0,0 +1,12 @@
+package org.apache.maven.continuum.release.maven2;
+
+import org.apache.maven.continuum.release.bean.ReleaseProject;
+
+public interface BuildExecutor {
+	String ROLE=BuildExecutor.class.getName();
+	
+	public int perform(ReleaseProject project);
+	public int prepare(ReleaseProject project);
+	public int rollback(ReleaseProject project);
+	public int check(ReleaseProject project);
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/ReleaseTaskExecutor.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/ReleaseTaskExecutor.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/ReleaseTaskExecutor.java	(revision 0)
@@ -0,0 +1,279 @@
+package org.apache.maven.continuum.release.executor;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.continuum.release.bean.ReleaseDependency;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor;
+import org.apache.maven.continuum.release.bean.ReleaseProject;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor.Status;
+import org.apache.maven.continuum.release.task.ReleaseProjectTask;
+import org.apache.maven.continuum.release.task.ReleaseTask;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.scm.ScmBranch;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmRevision;
+import org.apache.maven.scm.ScmTag;
+import org.apache.maven.scm.ScmVersion;
+import org.apache.maven.scm.command.checkout.CheckOutScmResult;
+import org.apache.maven.scm.manager.ScmManager;
+import org.codehaus.plexus.logging.LogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.taskqueue.Task;
+import org.codehaus.plexus.taskqueue.TaskQueue;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutor;
+
+public class ReleaseTaskExecutor implements TaskExecutor, LogEnabled{
+	Logger logger;
+	
+	ScmManager scmManager;
+	
+	//TODO this queue should be multithreaded. Change this when bug MNG-2802 will be fixed.  
+	private TaskQueue releaseProjectQueue;
+
+	/**
+	 * checkout the project.
+	 * 
+	 * @param workingDir
+	 * @param project
+	 * @param profile
+	 */
+	private Status checkoutProject(ReleaseProject project) {
+		CheckOutScmResult result;
+		try {
+			project.writeResultMessage("------------------ Checkout " + project.getProject().getArtifactId(), null);
+			String fromVersion = project.getFromVersion();
+			if(fromVersion == null) {
+				result = scmManager.checkOut(project.getScmRepository(), new ScmFileSet(project.getProjectDirectory()));
+			} else {
+				String versionType = project.getVersionType();
+				ScmVersion scmVersion;
+				if(versionType != null && versionType.equals("revision"))
+					scmVersion = new ScmRevision(fromVersion);
+				else if(versionType != null && versionType.equals("branch"))
+					scmVersion = new ScmBranch(fromVersion); 
+				else 
+					scmVersion = new ScmTag(fromVersion);
+				
+				result = scmManager.checkOut(project.getScmRepository(), new ScmFileSet(project.getProjectDirectory()),scmVersion);
+			}
+		} catch (Exception e) {
+			project.writeResultMessage("checkout failed for url :" + project.getProject().getScmUrl(), e);
+			return ReleaseDescriptor.Status.CHECKOUT_FAILED;
+		}
+		if (result.isSuccess()) {
+			project.writeResultMessage(result.getCommandLine() + "\n" + result.getCommandOutput(), null);
+			return ReleaseDescriptor.Status.CHECKOUT_SUCCESS;
+		} else {
+			project.writeResultMessage("checkout failed for url :" + result.getCommandLine() + "\n" + result.getCommandOutput(), null);
+			return ReleaseDescriptor.Status.CHECKOUT_FAILED;
+		}
+	}
+
+	@Override
+	public void executeTask(Task task) throws TaskExecutionException {
+		logger.info("Executing release.");
+		
+		ReleaseTask releaseTask = (ReleaseTask)task;
+		ReleaseDescriptor descriptor = releaseTask.getReleaseDescriptor();
+
+		//checkout all projects. 
+		//if a dependency is missing after checkout, stop the process and ask for missing dependencies.
+		Set<ReleaseDependency> missingSnapshotDependencies = new HashSet<ReleaseDependency>();
+		for (ReleaseProject project : releaseTask.getReleaseDescriptor().getProjectsToRelease()) {
+			Status result;
+			try {
+				result = checkoutProject(project);
+			} catch (Exception e) {
+				logger.error("fail to checkout " + project.getProject().getArtifactId(), e);
+				result = Status.CHECKOUT_FAILED;
+			}
+			project.setStatus(result);
+			if(result == Status.CHECKOUT_SUCCESS)  {
+				//Create the list of automatic dependencies versions for this project.
+				List<Dependency> snapshotDependencies;
+				try {
+					snapshotDependencies = getSnapshotDependencies(project);
+				} catch (Exception e) {
+					throw new TaskExecutionException("Can't read pom.xml.", e);
+				}
+				
+				Map<String, ReleaseDependency> projectDeps = project.getDependencies();
+				if(projectDeps==null) {
+					projectDeps = new HashMap<String, ReleaseDependency> ();
+					project.setDependencies(projectDeps);
+				}
+				for(Dependency dep : snapshotDependencies) {
+					if(projectDeps.get(dep.getGroupId() + ":" + dep.getArtifactId()) == null) {
+						//This dependency might miss!!! in this case, we should ask for it.
+						ReleaseProject depProject = descriptor.getReleaseProjectForArtifact(dep.getArtifactId());
+						ReleaseDependency releaseDep;
+						if(depProject == null ) {
+							//check in missingSnapshotDependencies
+							releaseDep = descriptor.getMissingSnapshotDependency(dep.getGroupId(), dep.getArtifactId());
+						} else
+							releaseDep = new ReleaseDependency(dep.getGroupId(), dep.getArtifactId(), depProject.getReleaseVersion(),
+									depProject.getNextDevelopmentVersion());
+							
+						if(releaseDep == null) {
+							releaseDep = new ReleaseDependency(dep.getGroupId(), dep.getArtifactId(), "","");
+							if(!missingSnapshotDependencies.contains(releaseDep))
+								missingSnapshotDependencies.add(releaseDep);
+						} else {
+							projectDeps.put(dep.getGroupId() + ":" + dep.getArtifactId(), releaseDep);
+						}
+					}
+				}
+				
+			}
+		}
+
+		if(!missingSnapshotDependencies.isEmpty()) {
+			descriptor.setSnapshotDependencies(missingSnapshotDependencies);	
+			return;
+		}
+			
+		//execute release
+		boolean isProjectToRelease = true;
+		while(isProjectToRelease) {
+			isProjectToRelease = false;
+			for(ReleaseProject project : releaseTask.getReleaseDescriptor().getProjectsToRelease()) {
+				Status status = project.getStatus();
+				if(status.compareTo(Status.CHECKOUT_SUCCESS) >= 0 && status.compareTo(Status.PREPARE_STARTED)<0) {
+					isProjectToRelease = true;
+					DependencyStatus depStatus = checkDependencies(project, descriptor);
+					switch(depStatus) {
+					case POM_READER_ERROR:
+						status = Status.INVALID_POM;
+						project.setStatus(status);
+						break;
+					case DEPENDENCY_FAILED:
+						status = Status.DEPENDENCY_FAILED;
+						project.setStatus(status);
+						break;
+					case DEPENDENCY_NOT_IN_RELEASE_LIST:
+						status = Status.DEPENDENCY_MISSING;
+						project.setStatus(status);
+						break;
+					case DEPENDENCY_OK:
+						//prepare release project.
+						try {
+								releaseProjectQueue.put(new ReleaseProjectTask(project, descriptor.getUsername(), descriptor.getPassword(), descriptor.isPrepareRelease(), descriptor.isPerformRelease()));
+								status = Status.PREPARE_STARTED;
+								project.setStatus(status);
+							} catch (Exception e) {
+								logger.error("Can't prepare project: " + project.getProject().getArtifactId(),e);
+								if(project.getStatus() != Status.PREPARE_FAILED)
+									project.setStatus(Status.PREPARE_FAILED);
+							}
+						break;
+					case DEPENDENCY_NOT_RELEASED:
+						//Do nothing. We can't migrate the project yet.
+						break;
+					}
+				} else if (status.compareTo(Status.PERFORM_SUCCESS)<0) {
+					isProjectToRelease = true;
+				}
+			}
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {}
+		}
+	}
+	
+	List<Dependency> getSnapshotDependencies(ReleaseProject project) throws Exception {
+		Model pom;
+		MavenXpp3Reader reader = new MavenXpp3Reader();
+		pom = reader.read(new InputStreamReader(new FileInputStream(
+				new File(project.getProjectDirectory(),
+						"pom.xml"))));
+		List<Dependency> snapshotDependencies = new ArrayList<Dependency>();
+		
+		for(Dependency dep : ((List<Dependency>)pom.getDependencies())) {
+			String version = dep.getVersion();
+			if(version == null) {
+				version = getVersionFromDepManagement(pom, dep);
+				dep.setVersion(version);
+			}
+			if(version.endsWith("-SNAPSHOT")) {
+				if(!snapshotDependencies.contains(dep))
+					snapshotDependencies.add(dep);
+			}
+		}
+		
+		//check SNAPSHOT in the dependency Management sections
+		if(pom.getDependencyManagement() != null && pom.getDependencyManagement().getDependencies() != null) {
+			for(Dependency dep : ((List<Dependency>)pom.getDependencyManagement().getDependencies())) {
+				String version = dep.getVersion();
+				if(version == null) {
+					version = getVersionFromDepManagement(pom, dep);
+					dep.setVersion(version);
+				}
+				if(version.endsWith("-SNAPSHOT")) {
+					if(!snapshotDependencies.contains(dep))
+						snapshotDependencies.add(dep);
+				}
+			}
+		}
+		return snapshotDependencies;
+		
+	}
+	
+	/**
+	 * 
+	 * @param project
+	 * @return
+	 */
+	DependencyStatus checkDependencies(ReleaseProject project, ReleaseDescriptor releaseDescriptor) {
+		List<Dependency> snapshotDependencies;
+		try {
+			snapshotDependencies = getSnapshotDependencies(project);
+		} catch (Exception e) {
+			return DependencyStatus.POM_READER_ERROR;
+		}
+		
+		for(Dependency dep : snapshotDependencies) {
+			String version = dep.getVersion();
+			if(version.endsWith("-SNAPSHOT")) {
+				//get dependency release project.
+				ReleaseProject depProject = releaseDescriptor.getReleaseProjectForArtifact(dep.getArtifactId());
+				if(depProject == null) {
+					if(releaseDescriptor.getMissingSnapshotDependency(dep.getGroupId(), dep.getArtifactId())!=null) {
+						continue;
+					}
+					return DependencyStatus.DEPENDENCY_NOT_IN_RELEASE_LIST;
+				}
+				Status depStatus = releaseDescriptor.getProjectsStatus(dep.getArtifactId()); 
+				if(depStatus.compareTo(Status.CHECKOUT_FAILED)>=0) {
+					return DependencyStatus.DEPENDENCY_FAILED;
+				} else if(depStatus.compareTo(Status.PERFORM_SUCCESS)<0)
+					return DependencyStatus.DEPENDENCY_NOT_RELEASED;
+			}
+		}
+		return DependencyStatus.DEPENDENCY_OK;
+	}
+	
+	String getVersionFromDepManagement(Model pom, Dependency dep) {
+		for(Dependency d : ((List<Dependency>)pom.getDependencyManagement().getDependencies())) {
+			if(d.getGroupId().equals(dep.getGroupId()) && d.getArtifactId().equals(dep.getArtifactId()))
+				return d.getVersion();
+			
+		}
+		return null;
+	}
+	public void enableLogging(Logger logger) {
+		this.logger = logger;
+	}
+	
+	static enum DependencyStatus {POM_READER_ERROR, DEPENDENCY_FAILED, DEPENDENCY_NOT_IN_RELEASE_LIST, DEPENDENCY_NOT_RELEASED, DEPENDENCY_OK}
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/ProjectAction.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/ProjectAction.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/ProjectAction.java	(revision 0)
@@ -0,0 +1,23 @@
+package org.apache.maven.continuum.release.executor;
+
+import org.apache.maven.continuum.release.bean.ReleaseProject;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
+
+public interface ProjectAction {
+	String ROLE = ProjectAction.class.getName();
+	
+	
+	public abstract void executePerform(ReleaseProject project, boolean isPerformOnly);
+
+	public abstract void executeRollback(ReleaseProject project);
+
+	/**
+	 * write the pom for release or for next dev version.
+	 * @param release
+	 * @return
+	 * @throws TaskExecutionException
+	 */
+	public abstract int writePomVersions(ReleaseProject project, boolean release)
+			throws TaskExecutionException;
+
+}
\ No newline at end of file
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/ReleaseProjectTaskExecutor.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/ReleaseProjectTaskExecutor.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/ReleaseProjectTaskExecutor.java	(revision 0)
@@ -0,0 +1,47 @@
+package org.apache.maven.continuum.release.executor;
+
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor.Status;
+import org.apache.maven.continuum.release.task.ReleaseProjectTask;
+import org.codehaus.plexus.logging.LogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.taskqueue.Task;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutor;
+
+public class ReleaseProjectTaskExecutor implements TaskExecutor, LogEnabled{
+	DefaultProjectAction projectAction;
+	
+	Logger logger;
+	
+	/**
+	 * Execute the prepare release, and the perform.
+	 */
+	@Override
+	public void executeTask(Task task) {
+		ReleaseProjectTask releaseProjectTask = (ReleaseProjectTask)task;
+		
+		if(releaseProjectTask.isPrepareRelease()) {
+			try {
+				if(projectAction.createBranch(releaseProjectTask.getReleaseProject()) == 0 && 
+						projectAction.prepareRelease(releaseProjectTask.getReleaseProject(), releaseProjectTask.getUsername(), releaseProjectTask.getPassword()) == 0) {
+					releaseProjectTask.getReleaseProject().setStatus(Status.PREPARE_SUCCESS);
+					projectAction.writePomVersions(releaseProjectTask.getReleaseProject(), false);
+				}else {
+					releaseProjectTask.getReleaseProject().setStatus(Status.PREPARE_FAILED);
+					projectAction.executeRollback(releaseProjectTask.getReleaseProject());
+				}
+			} catch (Throwable e) {
+				logger.error("Error preparing the release", e);
+				releaseProjectTask.getReleaseProject().setStatus(Status.PREPARE_FAILED);
+				projectAction.executeRollback(releaseProjectTask.getReleaseProject());
+			}
+		} 
+		
+		if(releaseProjectTask.isPerformRelease() && (!releaseProjectTask.isPrepareRelease() || releaseProjectTask.getReleaseProject().getStatus() == Status.PREPARE_SUCCESS)) {
+			projectAction.executePerform(releaseProjectTask.getReleaseProject(), !releaseProjectTask.isPrepareRelease());
+		}
+	}
+	
+	public void enableLogging(Logger arg0) {
+		this.logger = arg0;
+	}
+}
Index: continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/DefaultProjectAction.java
===================================================================
--- continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/DefaultProjectAction.java	(revision 0)
+++ continuum-release2/src/main/java/org/apache/maven/continuum/release/executor/DefaultProjectAction.java	(revision 0)
@@ -0,0 +1,302 @@
+package org.apache.maven.continuum.release.executor;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.continuum.release.bean.ReleaseDependency;
+import org.apache.maven.continuum.release.bean.ReleaseProject;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor.Status;
+import org.apache.maven.continuum.release.maven2.BuildExecutor;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
+import org.apache.maven.scm.ScmBranch;
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.command.branch.BranchScmResult;
+import org.apache.maven.scm.command.checkin.CheckInScmResult;
+import org.apache.maven.scm.command.checkout.CheckOutScmResult;
+import org.apache.maven.scm.manager.ScmManager;
+import org.codehaus.plexus.logging.LogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
+import org.codehaus.plexus.util.FileUtils;
+
+public class DefaultProjectAction implements LogEnabled, ProjectAction {
+
+	Logger logger;
+	ScmManager scmManager;
+	BuildExecutor buildExecutor;
+	
+	public void enableLogging(Logger arg0) {
+		this.logger = arg0;
+	}
+
+	
+	int createBranch(ReleaseProject project) {
+		//mvn scm:branch -Dbranch= -Dusername= -Dpassword=
+		String branch = project.getBranchName();
+		if(branch == null || branch.equals("")) {
+			//do not branch.
+			return 0;
+		}
+		project.writeResultMessage("------------ Creating branch " + branch, null);
+		File workingDir = project.getProjectDirectory();
+		try {
+			BranchScmResult result = scmManager.branch(project.getScmRepository(), new ScmFileSet(workingDir), 
+					branch);
+			if(!result.isSuccess()) {
+				logger.error("Branch fails for " + project.getProject().getArtifactId() +": " + result.getProviderMessage() +"\n" +
+						result.getCommandLine() + "\n"+
+						result.getCommandOutput());
+				project.writeResultMessage("Branch fails for " + project.getProject().getArtifactId() +": " + result.getProviderMessage() +"\n" +
+						result.getCommandLine() + "\n"+
+						result.getCommandOutput(), null);
+				return -1;
+			}
+			project.writeResultMessage(result.getCommandLine() + "\n"+
+					result.getCommandOutput(), null);
+		} catch (ScmException e) {
+			logger.error("Branch fails for " + project.getProject().getArtifactId() +": ", e);
+			project.writeResultMessage("Branch fails for " + project.getProject().getArtifactId() +": ", e);
+			return -1;
+		}
+
+		//checkout the branch 
+		project.writeResultMessage("------------ Checkout the branch", null);
+		ScmBranch scmBranch = new ScmBranch(branch);
+		try {
+			FileUtils.deleteDirectory(workingDir);
+			CheckOutScmResult result = scmManager.checkOut(project.getScmRepository(), new ScmFileSet(workingDir),scmBranch);
+			if(result.isSuccess()) {
+				project.writeResultMessage(result.getCommandLine() + "\n"+
+						result.getCommandOutput(), null);
+				return 0;
+			}
+			project.writeResultMessage("Checkout branch fails for " + project.getProject().getArtifactId() +": " + result.getProviderMessage() +"\n" +
+					result.getCommandLine() + "\n"+
+					result.getCommandOutput(), null);
+		} catch (Exception e) {
+			project.writeResultMessage("Checkout branch fails for " + project.getProject().getArtifactId() +": ", e);
+		}
+		return -1;
+	
+	}
+	/* (non-Javadoc)
+	 * @see org.apache.maven.continuum.release.executor.ProjectAction#executePerform(org.apache.maven.continuum.release.bean.ReleaseProject)
+	 */
+	public void executePerform(ReleaseProject project, boolean isPerformOnly) {
+		project.setStatus(Status.PERFORM_STARTED);
+	
+		try {
+			if(performRelease(project, isPerformOnly) == 0) {
+				project.setStatus(Status.PERFORM_SUCCESS);
+			}else {
+				project.setStatus(Status.PERFORM_FAILED);
+			}
+		} catch (Exception e) {
+			logger.error("fails to perform release: ", e);
+			project.setStatus(Status.PERFORM_FAILED);
+		}
+	}
+
+	public void executeRollback(ReleaseProject project) {
+		project.setStatus(Status.ROLLBACK_STARTED);
+	
+		try {
+			if(rollbackRelease(project) == 0) {
+				project.setStatus(Status.ROLLBACK_SUCCESS);
+			}else {
+				project.setStatus(Status.ROLLBACK_FAILED);
+			}
+		} catch (Exception e) {
+			logger.error("fails to rollback release: ", e);
+			project.setStatus(Status.ROLLBACK_FAILED);
+		}
+	}
+	
+	Dependency getVersionFromDepManagement(Model pom, Dependency dep) {
+		for(Dependency d : ((List<Dependency>)pom.getDependencyManagement().getDependencies())) {
+			if(d.getGroupId().equals(dep.getGroupId()) && d.getArtifactId().equals(dep.getArtifactId()))
+				return d;
+			
+		}
+		return null;
+	}
+	int performRelease(ReleaseProject project, boolean isPerformOnly) throws IOException {
+	    
+		project.writeResultMessage("------------------- Perform release", null);
+		writeReleaseProperties(project, null, null, isPerformOnly);
+		return buildExecutor.perform(project);
+	}
+	
+	int rollbackRelease(ReleaseProject project) throws IOException {
+		project.writeResultMessage("------------------- Rollback release", null);
+		if(!new File(project.getProjectDirectory(), "pom.xml.releaseBackup").exists())
+			logger.info("Can't do the rollback on " + project.getProject().getArtifactId());
+		else
+			buildExecutor.rollback(project);
+		//reset the pom with the saved one.
+		FileUtils.copyFile(new File(project.getProjectDirectory().getParentFile(), project.getProject().getArtifactId() + ".pre.pom"), new File(project.getProjectDirectory(), "pom.xml"));
+		commit(project, "[continuum release: Rollback pom.xml]");
+		return 0;
+	}
+	
+	int prepareRelease(ReleaseProject project, String username, String password) throws IOException, TaskExecutionException {
+		project.writeResultMessage("------------------- Prepare release", null);
+		//create a copy the pom.xml
+		FileUtils.copyFile(new File(project.getProjectDirectory(), "pom.xml"), new File(project.getProjectDirectory().getParentFile(), project.getProject().getArtifactId() + ".pre.pom"));
+		
+		//write the release.properties file.
+		writeReleaseProperties(project, username, password, false);
+		
+		//rewrite versions in pom.
+		if(writePomVersions(project,true) != 0)
+			throw new TaskExecutionException("can't prepare release because checkin of pom fails.");
+		
+		return buildExecutor.prepare(project);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.maven.continuum.release.executor.ProjectAction#writePomVersions(org.apache.maven.continuum.release.bean.ReleaseProject, boolean)
+	 */
+	public int writePomVersions(ReleaseProject project, boolean release) throws TaskExecutionException {
+	
+		Model pom;
+		File pomFile = new File(project.getProjectDirectory(), "pom.xml");
+		try {
+			MavenXpp3Reader reader = new MavenXpp3Reader();
+			pom = reader.read(new InputStreamReader(new FileInputStream(
+					pomFile)));
+	
+			for(Dependency dep : ((List<Dependency>)pom.getDependencies())) {
+				if(release) {
+					String version = dep.getVersion();
+					Dependency depForVersion = dep;
+					if(version == null) {
+						depForVersion = getVersionFromDepManagement(pom, dep);
+						version = depForVersion.getVersion(); 
+					}
+					if(version.endsWith("-SNAPSHOT")) {
+						//get dependency release project.
+						ReleaseDependency depProject = project.getDependencies().get(dep.getGroupId() + ":" + dep.getArtifactId());
+						String relVersion = depProject.getReleaseVersion();
+						depForVersion.setVersion(relVersion);
+					}
+				} else {
+					ReleaseDependency p = project.getDependencies().get(dep.getGroupId() + ":" + dep.getArtifactId());
+					if(p != null) {
+						String version = p.getNextDevVersion();
+						dep.setVersion(version);
+					}
+				}
+			}
+			
+			//Do the same with dependencyManagement if it exists.
+			if(pom.getDependencyManagement() != null && pom.getDependencyManagement().getDependencies() != null) {
+				for(Dependency dep : ((List<Dependency>)pom.getDependencyManagement().getDependencies())) {
+					if(release) {
+						String version = dep.getVersion();
+						Dependency depForVersion = dep;
+						if(version == null) {
+							depForVersion = getVersionFromDepManagement(pom, dep);
+							version = depForVersion.getVersion(); 
+						}
+						if(version.endsWith("-SNAPSHOT")) {
+							//get dependency release project.
+							ReleaseDependency depProject = project.getDependencies().get(dep.getGroupId() + ":" + dep.getArtifactId());
+							String relVersion = depProject.getReleaseVersion();
+							depForVersion.setVersion(relVersion);
+						}
+					} else {
+						ReleaseDependency p = project.getDependencies().get(dep.getGroupId() + ":" + dep.getArtifactId());
+						if(p != null) {
+							String version = p.getNextDevVersion();
+							dep.setVersion(version);
+						}
+					}
+				}
+			}			
+			
+			MavenXpp3Writer writer = new MavenXpp3Writer();
+			//wait 1 second before writing the file because the last changes could occurs in the same second and cvs wouldn't detect the change.
+			try {
+				Thread.sleep(1000);
+			}catch(IllegalStateException e) {}
+			writer.write(new PrintWriter(pomFile), pom);
+		} catch (Exception e) {
+			throw new TaskExecutionException("Can't find " + pomFile + " for " + project.getProject().getArtifactId(), e);
+		}
+		
+		//check that dependencies are correct before commiting
+		if (release && !checkResolveDependencies(project)) {
+			logger.error("Versions can't be resolved.");
+			return -1;
+		}
+
+		return commit(project, "[continuum release: Update SNAPSHOT dependencies]");
+	}
+
+	
+	int commit(ReleaseProject project, String commitMessage) {
+		//commit changes.
+		CheckInScmResult result = null; 
+		try {
+			result = scmManager.checkIn(project.getScmRepository(), new ScmFileSet(project.getProjectDirectory()), 
+					commitMessage);
+			if(result.isSuccess()) {
+				project.writeResultMessage(project.getProject().getArtifactId() +": " + result.getProviderMessage() +"\n" +
+						result.getCommandLine() + "\n"+
+						result.getCommandOutput(), null);
+				return 0;
+			}
+
+			project.writeResultMessage("Commit fails for " + project.getProject().getArtifactId() +": " + result.getProviderMessage() +"\n" +
+					result.getCommandLine() + "\n"+
+					result.getCommandOutput(), null);
+		} catch (ScmException e) {
+			project.writeResultMessage("Commit fails for " + project.getProject().getArtifactId() +": ", null);
+			if(result != null) {
+				project.writeResultMessage(result.getCommandOutput(), null);
+			}
+			project.writeResultMessage("", e);
+		}
+		return -1;
+	}
+	
+	boolean checkResolveDependencies(ReleaseProject project) {
+		return buildExecutor.check(project) == 0;
+	}
+	
+	void writeReleaseProperties(ReleaseProject project, String username, String password, boolean performOnly) throws IOException {
+        File releasePropertiesFile = new File(project.getProjectDirectory(), "release.properties");
+        if(releasePropertiesFile.exists())
+            return;
+		Properties props = new Properties();
+		String releaseTag = project.getReleaseTag();
+		
+		String devVersion = project.getNextDevelopmentVersion();
+		
+		String releaseVersion = project.getReleaseVersion();
+		if(!performOnly) {
+		    props.setProperty("scm.tag", releaseTag);
+	        props.setProperty("scm.username", (username!=null?username:""));
+	        props.setProperty("scm.password", (password!=null?password:""));
+	        props.setProperty("project.dev." + project.getProject().getGroupId() + ":" + project.getProject().getArtifactId(), devVersion);
+	        props.setProperty("project.rel." + project.getProject().getGroupId() + ":" + project.getProject().getArtifactId(), releaseVersion);
+            props.setProperty("completedPhase", "");
+		} else if(project.getVersionType() != null && (project.getVersionType().equals("tag") || project.getVersionType().equals("branch")))
+		    props.setProperty("scm.tag", project.getFromVersion()); //We should release the 
+		props.setProperty("scm.url", project.getProject().getScmUrl());
+		
+		props.store(new PrintWriter(releasePropertiesFile), "release configuration");
+	
+	}
+
+}
Index: continuum-release2/src/main/resources/META-INF/plexus/components.xml
===================================================================
--- continuum-release2/src/main/resources/META-INF/plexus/components.xml	(revision 0)
+++ continuum-release2/src/main/resources/META-INF/plexus/components.xml	(revision 0)
@@ -0,0 +1,175 @@
+<!--
+  ~ 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.
+  -->
+
+<component-set>
+  <components>
+    <component>
+      <role>org.apache.maven.continuum.release.ProjectReleaseManager</role>
+      <role-hint>default</role-hint>
+      <implementation>org.apache.maven.continuum.release.DefaultProjectReleaseManager</implementation>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
+          <role-hint>release2</role-hint>
+          <field-name>releaseQueue</field-name>
+        </requirement>
+        <requirement>
+          <role>org.apache.maven.scm.manager.ScmManager</role>
+          <field-name>scmManager</field-name>
+        </requirement>        
+      </requirements>
+    </component>
+
+    <!--
+     |
+     | Release Task Queue
+     |
+     |-->
+
+    <component>
+      <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
+      <role-hint>release2</role-hint>
+      <implementation>org.codehaus.plexus.taskqueue.DefaultTaskQueue</implementation>
+      <lifecycle-handler>plexus-configurable</lifecycle-handler>
+      <configuration>
+        <task-entry-evaluators>
+        </task-entry-evaluators>
+        <task-exit-evaluators>
+        </task-exit-evaluators>
+        <task-viability-evaluators>
+        </task-viability-evaluators>
+      </configuration>
+    </component>
+
+    <component>
+      <role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
+      <role-hint>release2</role-hint>
+      <implementation>org.apache.maven.continuum.release.executor.ReleaseTaskExecutor</implementation>
+      <requirements>
+        <requirement>
+          <role>org.apache.maven.scm.manager.ScmManager</role>
+          <field-name>scmManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
+          <role-hint>releaseProject2</role-hint>
+          <field-name>releaseProjectQueue</field-name>
+        </requirement>        
+      </requirements>
+    </component>
+
+    <component>
+      <role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
+      <role-hint>release2</role-hint>
+      <implementation>org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor</implementation>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
+          <role-hint>release2</role-hint>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
+          <role-hint>release2</role-hint>
+        </requirement>
+      </requirements>
+      <configuration>
+        <name>release2</name>
+      </configuration>
+    </component>
+
+
+    <!--
+     |
+     | Release Project Task Queue
+     |
+     |-->
+
+    <component>
+      <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
+      <role-hint>releaseProject2</role-hint>
+      <implementation>org.codehaus.plexus.taskqueue.DefaultTaskQueue</implementation>
+      <lifecycle-handler>plexus-configurable</lifecycle-handler>
+      <configuration>
+        <task-entry-evaluators>
+        </task-entry-evaluators>
+        <task-exit-evaluators>
+        </task-exit-evaluators>
+        <task-viability-evaluators>
+        </task-viability-evaluators>
+      </configuration>
+    </component>
+
+    <component>
+      <role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
+      <role-hint>releaseProject2</role-hint>
+      <implementation>org.apache.maven.continuum.release.executor.ReleaseProjectTaskExecutor</implementation>
+      <requirements>
+        <requirement>
+          <role>org.apache.maven.continuum.release.executor.ProjectAction</role>
+          <field-name>projectAction</field-name>
+        </requirement>
+      </requirements>
+    </component>
+
+    <component>
+      <role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
+      <role-hint>releaseProject2</role-hint>
+      <implementation>org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor</implementation>
+      <requirements>
+        <requirement>
+          <role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
+          <role-hint>releaseProject2</role-hint>
+        </requirement>
+        <requirement>
+          <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
+          <role-hint>releaseProject2</role-hint>
+        </requirement>
+      </requirements>
+      <configuration>
+        <name>releaseProject2</name>
+      </configuration>
+    </component>
+
+
+    <component>
+      <role>org.apache.maven.continuum.release.executor.ProjectAction</role>
+      <implementation>org.apache.maven.continuum.release.executor.DefaultProjectAction</implementation>
+      <requirements>
+        <requirement>
+          <role>org.apache.maven.scm.manager.ScmManager</role>
+          <field-name>scmManager</field-name>
+        </requirement>
+        <requirement>
+          <role>org.apache.maven.continuum.release.maven2.BuildExecutor</role>
+          <role-hint>maven</role-hint>
+          <field-name>buildExecutor</field-name>
+        </requirement>        
+      </requirements>
+    </component>
+    
+    <component>
+      <role>org.apache.maven.continuum.release.maven2.BuildExecutor</role>
+      <role-hint>maven</role-hint>
+      <implementation>org.apache.maven.continuum.release.maven2.MavenBuildExecutor</implementation>
+    </component>
+    
+    
+  </components>
+
+</component-set>
Index: continuum-release2/pom.xml
===================================================================
--- continuum-release2/pom.xml	(revision 0)
+++ continuum-release2/pom.xml	(revision 0)
@@ -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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>continuum</artifactId>
+    <groupId>org.apache.continuum</groupId>
+    <version>1.2-SNAPSHOT</version>
+  </parent>
+  <artifactId>continuum-release2</artifactId>
+  <name>Continuum Release2 System</name>
+  <description>
+    Take a release descriptor created by the Maven Release Plugin and use that to perform the actual
+    release.
+  </description>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.continuum</groupId>
+      <artifactId>continuum-model</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.continuum</groupId>
+      <artifactId>continuum-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.continuum</groupId>
+      <artifactId>continuum-commons</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-settings</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-project</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-model</artifactId>
+    </dependency>
+    <!--
+      adding maven-artifact as a dependency since maven-2.0.5-SNAPSHOT
+      appears to have a slightly different way of resolving dependencies
+      and 2.0 artifact is getting chosen as opposed to 2.0.4 like earlier
+      versions of maven peg it to...the 2.0 artifact was coming from the
+      maven-release-manager
+    -->
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-artifact</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-artifact-manager</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.release</groupId>
+      <artifactId>maven-release-manager</artifactId>
+      <version>1.0-alpha-3</version>
+      <exclusions>
+        <exclusion>
+          <groupId>classworlds</groupId>
+          <artifactId>classworlds</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-taskqueue</artifactId>
+    </dependency>
+    <!-- 
+    <dependency>
+      <groupId>org.apache.maven.scm</groupId>
+      <artifactId>maven-scm-api</artifactId>
+      <version>${maven-scm.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.scm</groupId>
+      <artifactId>maven-scm-manager-plexus</artifactId>
+      <version>${maven-scm.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.scm</groupId>
+      <artifactId>maven-scm-provider-bazaar</artifactId>
+      <version>${maven-scm.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.scm</groupId>
+      <artifactId>maven-scm-provider-clearcase</artifactId>
+      <version>${maven-scm.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.scm</groupId>
+      <artifactId>maven-scm-provider-cvsjava</artifactId>
+      <version>${maven-scm.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.scm</groupId>
+      <artifactId>maven-scm-provider-cvsexe</artifactId>
+      <version>${maven-scm.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.scm</groupId>
+      <artifactId>maven-scm-provider-local</artifactId>
+      <version>${maven-scm.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.scm</groupId>
+      <artifactId>maven-scm-provider-perforce</artifactId>
+      <version>${maven-scm.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.scm</groupId>
+      <artifactId>maven-scm-provider-starteam</artifactId>
+      <version>${maven-scm.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.scm</groupId>
+      <artifactId>maven-scm-provider-svnexe</artifactId>
+      <version>${maven-scm.version}</version>
+    </dependency>
+     -->
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>1.2.8</version>
+    </dependency>
+    <!-- === Testing Dependencies === -->
+    <dependency>
+      <groupId>hsqldb</groupId>
+      <artifactId>hsqldb</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.continuum</groupId>
+      <artifactId>continuum-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <testResources>
+      <testResource>
+        <directory>src/test/scm</directory>
+        <targetPath>../scm-src</targetPath>
+      </testResource>
+    </testResources>
+  </build>
+</project>
Index: continuum-release2/release.properties
===================================================================
--- continuum-release2/release.properties	(revision 0)
+++ continuum-release2/release.properties	(revision 0)
@@ -0,0 +1,8 @@
+#release configuration
+#Mon Mar 24 15:53:15 CET 2008
+preparationGoals=clean install
+scm.commentPrefix=[maven-release-plugin] 
+scm.tagBase=https\://svn.apache.org/repos/asf/continuum/tags
+exec.additionalArguments=-Prelease -P default_profile,default_profile
+completedPhase=scm-check-modifications
+scm.url=scm\:svn\:https\://svn.apache.org/repos/asf/continuum/branches/continuum-1.x/continuum-release2
Index: continuum-release2/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- continuum-release2/.settings/org.eclipse.jdt.core.prefs	(revision 0)
+++ continuum-release2/.settings/org.eclipse.jdt.core.prefs	(revision 0)
@@ -0,0 +1,12 @@
+#Wed Mar 12 15:13:13 CET 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
Index: continuum-release2/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- continuum-release2/.settings/org.maven.ide.eclipse.prefs	(revision 0)
+++ continuum-release2/.settings/org.maven.ide.eclipse.prefs	(revision 0)
@@ -0,0 +1,9 @@
+#Thu May 15 10:14:20 CEST 2008
+activeProfiles=
+eclipse.preferences.version=1
+filterResources=false
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+useMavenFolders=false
+version=1
Index: continuum-webapp/src/main/java/org/apache/continuum/web/startup/ContinuumStartup.java
===================================================================
--- continuum-webapp/src/main/java/org/apache/continuum/web/startup/ContinuumStartup.java	(revision 659128)
+++ continuum-webapp/src/main/java/org/apache/continuum/web/startup/ContinuumStartup.java	(working copy)
@@ -76,6 +76,12 @@
         TaskQueueExecutor rollbackRelease = (TaskQueueExecutor) wac.getBean( PlexusToSpringUtils
             .buildSpringId( TaskQueueExecutor.class, "rollback-release" ) );        
 
+        wac.getBean( PlexusToSpringUtils
+            .buildSpringId( TaskQueueExecutor.class, "release2" ) );        
+
+        wac.getBean( PlexusToSpringUtils
+            .buildSpringId( TaskQueueExecutor.class, "releaseProject2" ) );        
+
         try
         {
             continuum.startup();
Index: continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/Release2PrepareAction.java
===================================================================
--- continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/Release2PrepareAction.java	(revision 0)
+++ continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/Release2PrepareAction.java	(revision 0)
@@ -0,0 +1,469 @@
+package org.apache.maven.continuum.web.action;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.continuum.ContinuumException;
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.model.system.Profile;
+import org.apache.maven.continuum.release.ProjectReleaseManager;
+import org.apache.maven.continuum.release.bean.ReleaseDependency;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor;
+import org.apache.maven.continuum.release.bean.ReleaseProject;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Benoit Decherf
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="release2Prepare"
+ */
+public class Release2PrepareAction
+    extends Release2AbstractAction
+{
+	private static final long serialVersionUID = 1680955677883481557L;
+
+	private final static String MISSING_INFORMATIONS = "MISSING_INFORMATIONS";
+	
+	private String releaseId;
+    
+    private List<String> projectId;
+    
+    private List<String> selectedProjects; //To generate release of selected projects.
+    
+    private int projectGroupId;
+    
+    private int profileId;
+    
+    private boolean prepareRelease;
+    
+    private boolean performRelease;
+
+    private ReleaseDescriptor descriptor;
+
+    String projectGroupName;
+    
+    List<Profile> profiles;
+    
+    private List<String> ids;
+    private List<String> fromVersions;
+    private List<String> versionTypes;
+    private List<String> branchNames;
+    private List<String> releaseTags;
+    private List<String> releaseVersions;
+    private List<String> devVersions;
+    
+    //for snapshot dependencies.
+    private List<String> depGroupIds;
+    private List<String> depArtifactIds;
+    private List<String> depReleaseVersions;
+    private List<String> depDevVersions;
+
+    private List<String> defaultVersionTypes = Arrays.asList(new String[] {"", "tag", "revision"});
+    
+    boolean finished;
+    
+    private String result;
+    
+    public String input()
+        throws Exception
+    {
+    	/*
+        try
+        {
+            checkBuildProjectInGroupAuthorization( getProjectGroupName() );
+        }
+        catch ( AuthorizationRequiredException e )
+        {
+            return REQUIRES_AUTHORIZATION;
+        }
+        */
+    	if(releaseId != null)
+    		descriptor = releaseDescriptors.get(releaseId);
+    	if(descriptor == null) {
+	        descriptor = new ReleaseDescriptor();
+	        descriptor.setBuildDirectory(getContinuum().getConfiguration().getBuildOutputDirectory().getAbsolutePath());
+	        descriptor.setReleaseTag("${project.artifactId}_${project.version}");
+	        
+	        List<ReleaseProject> projects = descriptor.getProjectsToRelease();
+	        if(projects == null) {
+	        	projects = new ArrayList<ReleaseProject>();
+	        	descriptor.setProjectsToRelease(projects);
+	        }
+	        	
+	        
+	        if(projectId != null && !projectId.isEmpty()) {
+	        	for(String pId : projectId) {
+		        	ReleaseProject releaseProject = new ReleaseProject();
+		        	Project continuumProject = getContinuum().getProject(Integer.parseInt(pId));
+		    		releaseProject.setProject(continuumProject);
+		    		if(continuumProject.getScmTag() != null) {
+		    			releaseProject.setFromVersion(continuumProject.getScmTag());
+		    			releaseProject.setVersionType("branch");
+		    		}
+	    			releaseProject.setReleaseVersion(getReleaseVersion(continuumProject));
+	    			releaseProject.setNextDevelopmentVersion(getNextDevelopmentVersion(continuumProject));
+		    		projects.add(releaseProject);
+	        	}
+	        } else if(selectedProjects != null && !selectedProjects.isEmpty()) {
+	        	for(String pId : selectedProjects) {
+		        	ReleaseProject releaseProject = new ReleaseProject();
+		        	Project continuumProject = getContinuum().getProject(Integer.parseInt(pId));
+		    		releaseProject.setProject(continuumProject);
+		    		if(continuumProject.getScmTag() != null) {
+		    			releaseProject.setFromVersion(continuumProject.getScmTag());
+		    			releaseProject.setVersionType("branch");
+		    		}
+	    			releaseProject.setReleaseVersion(getReleaseVersion(continuumProject));
+	    			releaseProject.setNextDevelopmentVersion(getNextDevelopmentVersion(continuumProject));
+		    		projects.add(releaseProject);
+	        	}
+    		} else if(projectGroupId != 0) {
+	        	for (Project project : getContinuum().getProjectsInGroup(projectGroupId)) {
+	        		ReleaseProject releaseProject = new ReleaseProject();
+		    		if(project.getScmTag() != null) {
+		    			releaseProject.setFromVersion(project.getScmTag());
+		    			releaseProject.setVersionType("branch");
+		    		}
+	    			releaseProject.setReleaseVersion(getReleaseVersion(project));
+	    			releaseProject.setNextDevelopmentVersion(getNextDevelopmentVersion(project));
+	        		releaseProject.setProject(project);
+	        		projects.add(releaseProject);
+	        	}
+	        } 
+    	}
+    	performRelease = descriptor.isPerformRelease();
+    	prepareRelease = descriptor.isPrepareRelease();
+    	
+        profiles = getContinuum().getProfileService().getAllProfiles();
+        
+        return SUCCESS;
+    }
+    String getReleaseVersion(Project continuumProject) {
+    	String version = continuumProject.getVersion();
+    	if(version.endsWith("-SNAPSHOT"))
+    		return version.substring(0, version.indexOf("-SNAPSHOT"));
+    	else
+    		return "";
+    }
+    
+    String getNextDevelopmentVersion(Project continuumProject) {
+    	String version = getReleaseVersion(continuumProject);
+    	if(version == null || version.length()==0)
+    		return "";
+    	String patchStr = version.substring(version.lastIndexOf(".")+1);
+    	try {
+    		Integer patchNumber = Integer.parseInt(patchStr);
+    		return version.substring(0, version.lastIndexOf(".")+1) + (patchNumber+1) + "-SNAPSHOT";
+    	} catch (NumberFormatException e) {} //Ignore it.
+    	return "";
+    }
+    
+    
+    public String execute()
+        throws Exception
+    {
+    	/*
+        try
+        {
+            checkBuildProjectInGroupAuthorization( getProjectGroupName() );
+        }
+        catch ( AuthorizationRequiredException e )
+        {
+            return REQUIRES_AUTHORIZATION;
+        }
+*/
+    	createDescriptor();
+    	getLogger().info("Using user : " + descriptor.getUsername());
+    	getLogger().info("Releasing " +  descriptor.getProjectsToRelease().size()  +" projects.");
+        releaseManager.releaseProjects(descriptor);
+        if(releaseDescriptors == null)
+        	releaseDescriptors = new HashMap<String, ReleaseDescriptor>();
+        releaseDescriptors.put(descriptor.getReleaseId(), descriptor);
+        finished=descriptor.isReleaseFinished();
+        return SUCCESS;
+    }
+
+    void createDescriptor() throws NumberFormatException, ContinuumException {
+    	List<ReleaseProject> projects = new ArrayList<ReleaseProject>();
+    	 
+    	if(descriptor == null)
+    		descriptor = new ReleaseDescriptor();
+    	
+    	for(int i = 0; i < ids.size(); i++) {
+    		String id = ids.get(i);
+    		ReleaseProject releaseProject = new ReleaseProject();
+    		releaseProject.setProject(getContinuum().getProject(Integer.parseInt(id)));
+    		releaseProject.setBranchName(branchNames.get(i));
+    		releaseProject.setFromVersion(fromVersions.get(i));
+    		releaseProject.setNextDevelopmentVersion(devVersions.get(i));
+    		releaseProject.setReleaseTag(releaseTags.get(i));
+    		releaseProject.setReleaseVersion(releaseVersions.get(i));
+    		releaseProject.setVersionType(versionTypes.get(i));
+    		projects.add(releaseProject);
+    	}
+    	Set<ReleaseDependency> dependencies = new HashSet<ReleaseDependency>();
+    	if(depGroupIds != null) {
+	    	for(int i = 0; i < depGroupIds.size(); i++) {
+	    		dependencies.add(new ReleaseDependency(depGroupIds.get(i), 
+	    				depArtifactIds.get(i),
+	    				depReleaseVersions.get(i),
+	    				depDevVersions.get(i)));
+	    	}
+	    	descriptor.setSnapshotDependencies(dependencies);
+    	}
+    	descriptor.setPerformRelease(performRelease);
+    	descriptor.setPrepareRelease(prepareRelease);
+    	
+    	descriptor.setProjectsToRelease(projects);
+        descriptor.setBuildDirectory(getContinuum().getConfiguration().getBuildOutputDirectory().getAbsolutePath());
+        descriptor.setProfile(getContinuum().getProfileService().getProfile(profileId));
+    }
+    
+    public String viewResult()
+        throws Exception
+    {	
+    	/*
+        try
+        {
+            checkBuildProjectInGroupAuthorization( getProjectGroupName() );
+        }
+        catch ( AuthorizationRequiredException e )
+        {
+            return REQUIRES_AUTHORIZATION;
+        }
+		*/
+    	descriptor = releaseDescriptors.get(releaseId);
+    	if(descriptor == null)
+    		getLogger().warn("The releaseId " + releaseId + " was not found in the " + releaseDescriptors.size() + " release descriptors.");
+    	else
+    		finished=descriptor.isReleaseFinished();
+    	if(descriptor.getSnapshotDependencies()!= null && !descriptor.getSnapshotDependencies().isEmpty()) {
+    		for(ReleaseDependency dep : descriptor.getSnapshotDependencies()) {
+    			if(dep.getNextDevVersion()==null || dep.getNextDevVersion().equals("") ||
+    					dep.getReleaseVersion() == null || dep.getReleaseVersion().equals(""))
+    				return MISSING_INFORMATIONS;
+    		}
+    		
+    	}
+        return SUCCESS;
+    }
+
+	public List<String> getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(List<String> projectId) {
+		this.projectId = projectId;
+	}
+
+	public int getProjectGroupId() {
+		return projectGroupId;
+	}
+
+	public void setProjectGroupId(int projectGroupId) {
+		this.projectGroupId = projectGroupId;
+	}
+
+	public ReleaseDescriptor getDescriptor() {
+		return descriptor;
+	}
+
+	public void setDescriptor(ReleaseDescriptor descriptor) {
+		this.descriptor = descriptor;
+	}
+
+	public ProjectReleaseManager getReleaseManager() {
+		return releaseManager;
+	}
+
+	public void setReleaseManager(ProjectReleaseManager releaseManager) {
+		this.releaseManager = releaseManager;
+	}
+
+	public String getReleaseId() {
+		return releaseId;
+	}
+
+	public void setReleaseId(String releaseId) {
+		this.releaseId = releaseId;
+	}
+
+	public List<String> getIds() {
+		return ids;
+	}
+
+	public void setIds(List<String> ids) {
+		this.ids = ids;
+	}
+
+	public List<String> getFromVersions() {
+		return fromVersions;
+	}
+
+	public void setFromVersions(List<String> fromVersions) {
+		this.fromVersions = fromVersions;
+	}
+
+	public List<String> getVersionTypes() {
+		return versionTypes;
+	}
+
+	public void setVersionTypes(List<String> versionTypes) {
+		this.versionTypes = versionTypes;
+	}
+
+	public List<String> getBranchNames() {
+		return branchNames;
+	}
+
+	public void setBranchNames(List<String> branchNames) {
+		this.branchNames = branchNames;
+	}
+
+	public List<String> getReleaseTags() {
+		return releaseTags;
+	}
+
+	public void setReleaseTags(List<String> releaseTags) {
+		this.releaseTags = releaseTags;
+	}
+
+	public List<String> getReleaseVersions() {
+		return releaseVersions;
+	}
+
+	public void setReleaseVersions(List<String> releaseVersions) {
+		this.releaseVersions = releaseVersions;
+	}
+
+	public List<String> getDevVersions() {
+		return devVersions;
+	}
+
+	public void setDevVersions(List<String> devVersions) {
+		this.devVersions = devVersions;
+	}
+
+	public boolean isFinished() {
+		return finished;
+	}
+
+	public void setFinished(boolean finished) {
+		this.finished = finished;
+	}
+
+	public List<Profile> getProfiles() {
+		return profiles;
+	}
+
+	public void setProfiles(List<Profile> profiles) {
+		this.profiles = profiles;
+	}
+
+	public String getResult() {
+		return result;
+	}
+
+	public void setResult(String result) {
+		this.result = result;
+	}
+
+	public int getProfileId() {
+		return profileId;
+	}
+
+	public void setProfileId(int profileId) {
+		this.profileId = profileId;
+	}
+
+	public List<String> getVersionType() {
+		return defaultVersionTypes;
+	}
+
+	public void setVersionType(List<String> versionType) {
+		this.defaultVersionTypes = versionType;
+	}
+
+	public List<String> getDepGroupIds() {
+		return depGroupIds;
+	}
+
+	public void setDepGroupIds(List<String> depGroupIds) {
+		this.depGroupIds = depGroupIds;
+	}
+
+	public List<String> getDepArtifactIds() {
+		return depArtifactIds;
+	}
+
+	public void setDepArtifactIds(List<String> depArtifactIds) {
+		this.depArtifactIds = depArtifactIds;
+	}
+
+	public List<String> getDepDevVersions() {
+		return depDevVersions;
+	}
+
+	public void setDepDevVersions(List<String> depDevVersions) {
+		this.depDevVersions = depDevVersions;
+	}
+
+	public List<String> getDefaultVersionTypes() {
+		return defaultVersionTypes;
+	}
+
+	public void setDefaultVersionTypes(List<String> defaultVersionTypes) {
+		this.defaultVersionTypes = defaultVersionTypes;
+	}
+
+	public List<String> getDepReleaseVersions() {
+		return depReleaseVersions;
+	}
+
+	public void setDepReleaseVersions(List<String> depReleaseVersions) {
+		this.depReleaseVersions = depReleaseVersions;
+	}
+
+	public boolean isPrepareRelease() {
+		return prepareRelease;
+	}
+
+	public void setPrepareRelease(boolean prepareRelease) {
+		this.prepareRelease = prepareRelease;
+	}
+
+	public boolean isPerformRelease() {
+		return performRelease;
+	}
+
+	public void setPerformRelease(boolean performRelease) {
+		this.performRelease = performRelease;
+	}
+	public List<String> getSelectedProjects() {
+		return selectedProjects;
+	}
+	public void setSelectedProjects(List<String> selectedProjects) {
+		this.selectedProjects = selectedProjects;
+	}
+}
Index: continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/Release2AbstractAction.java
===================================================================
--- continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/Release2AbstractAction.java	(revision 0)
+++ continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/Release2AbstractAction.java	(revision 0)
@@ -0,0 +1,20 @@
+package org.apache.maven.continuum.web.action;
+
+import java.util.Map;
+
+import org.apache.maven.continuum.release.ProjectReleaseManager;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor;
+
+public class Release2AbstractAction extends ContinuumActionSupport {
+
+	protected static Map<String, ReleaseDescriptor> releaseDescriptors;
+	/**
+	 * @plexus.requirement role-hint="default"
+	 */
+	protected ProjectReleaseManager releaseManager;
+
+	public Release2AbstractAction() {
+		super();
+	}
+
+}
\ No newline at end of file
Index: continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/Release2ViewResultAction.java
===================================================================
--- continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/Release2ViewResultAction.java	(revision 0)
+++ continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/Release2ViewResultAction.java	(revision 0)
@@ -0,0 +1,127 @@
+package org.apache.maven.continuum.web.action;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.continuum.ContinuumException;
+import org.apache.maven.continuum.release.bean.ReleaseDescriptor;
+import org.apache.maven.continuum.release.bean.ReleaseProject;
+import org.codehaus.plexus.action.ActionException;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+
+/**
+ * @author Benoit Decherf
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="release2ViewResult"
+ */
+public class Release2ViewResultAction
+    extends Release2AbstractAction
+{
+	private static final long serialVersionUID = 1680955677883481557L;
+    private String releaseId;
+    
+    private Integer projectId;
+
+    private ReleaseDescriptor descriptor;
+    
+    String projectGroupName;
+
+    boolean finished;
+    
+    private String result;
+
+    public String viewProjectResult() throws Exception {
+    	descriptor = releaseDescriptors.get(releaseId);
+    	if(descriptor == null)
+    		getLogger().warn("The releaseId " + releaseId + " was not found in the " + releaseDescriptors.size() + " release descriptors.");
+    	else
+    		finished=descriptor.isReleaseFinished();
+
+    	ReleaseProject project = getProject();
+    	if(project == null)
+    		throw new ActionException("can't find project with id " + projectId + " for release " + releaseId);
+    	if(project.getStreamConsumer() != null) {
+    		BufferedReader br = new BufferedReader(new InputStreamReader(
+    				new FileInputStream(descriptor.getBuildDirectory() + File.separator+ descriptor.getReleaseId() + File.separator + 
+    						project.getProject().getArtifactId() + ".log")));
+    		StringBuffer resultBuffer = new StringBuffer();
+    		for(String line = br.readLine(); line != null; line = br.readLine()) {
+    			resultBuffer.append(line).append("\n");
+    		}
+    		result = resultBuffer.toString();
+    	}
+    	else result = "No output";
+    	return SUCCESS;
+    }
+    
+    protected ReleaseProject getProject() {
+    	for(ReleaseProject project : descriptor.getProjectsToRelease())
+    		if(project.getProject().getId() == projectId)
+    			return project;
+    	return null;
+    }
+    
+    public String getProjectGroupName()
+        throws ContinuumException
+    {
+        if ( StringUtils.isEmpty( projectGroupName ) )
+        {
+        	if(projectId!=0)
+        		projectGroupName = getContinuum().getProjectGroupByProjectId( projectId ).getName();
+        }
+
+        return projectGroupName;
+    }
+
+	public boolean isFinished() {
+		return finished;
+	}
+
+	public void setFinished(boolean finished) {
+		this.finished = finished;
+	}
+	
+	public int getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(int projectId) {
+		this.projectId = projectId;
+	}
+
+	public String getReleaseId() {
+		return releaseId;
+	}
+
+	public void setReleaseId(String releaseId) {
+		this.releaseId = releaseId;
+	}
+
+	public String getResult() {
+		return result;
+	}
+
+	public void setResult(String result) {
+		this.result = result;
+	}
+}
Index: continuum-webapp/src/main/resources/localization/Continuum.properties
===================================================================
--- continuum-webapp/src/main/resources/localization/Continuum.properties	(revision 659128)
+++ continuum-webapp/src/main/resources/localization/Continuum.properties	(working copy)
@@ -173,6 +173,7 @@
 projectGroup.buildsStatut.success = Success
 projectGroup.buildDefinition.label = Default Build Definition
 projectGroup.addProject.label = Add New Project
+projectGroup.releaseBuilds = Release Project(s)
 
 # ----------------------------------------------------------------------
 # Page: Project Group - Members
Index: continuum-webapp/src/main/resources/xwork.xml
===================================================================
--- continuum-webapp/src/main/resources/xwork.xml	(revision 659128)
+++ continuum-webapp/src/main/resources/xwork.xml	(working copy)
@@ -437,6 +437,37 @@
     </action>    
 
     <!--
+    - continuum release2
+    -->
+    <action name="release2Input" class="release2Prepare" method="input">
+      <result name="success">/WEB-INF/jsp/releaseInput.jsp</result>
+    </action>
+
+    <action name="release2Execute" class="release2Prepare" method="execute">
+      <result name="success">/WEB-INF/jsp/releaseResultSummary.jsp</result>
+      <result name="input" type="chain">release2Input</result>
+    </action>
+
+    <action name="release2Result" class="release2Prepare" method="viewResult">
+      <result name="success">/WEB-INF/jsp/releaseResultSummary.jsp</result>
+      <result name="error">/WEB-INF/jsp/components/failureComponent.jsp</result>
+      <result name="MISSING_INFORMATIONS" type="chain">release2Input</result>
+    </action>
+
+    <action name="release2ProjectResult" class="release2ViewResult" method="viewProjectResult">
+      <result name="success">/WEB-INF/jsp/releaseProjectResult.jsp</result>
+      <result name="error">/WEB-INF/jsp/components/failureComponent.jsp</result>
+    </action>
+
+    <!--
+    <action name="release2Prepare" class="release2Prepare">
+      <result name="success">/WEB-INF/jsp/releaseInput.jsp</result>
+    </action>
+     -->
+
+
+
+    <!--
     - continuum release
     -->
     <action name="releasePromptGoal" class="releaseProject" method="promptReleaseGoal">
Index: continuum-webapp/src/main/webapp/WEB-INF/jsp/components/projectSummaryComponent.jsp
===================================================================
--- continuum-webapp/src/main/webapp/WEB-INF/jsp/components/projectSummaryComponent.jsp	(revision 659128)
+++ continuum-webapp/src/main/webapp/WEB-INF/jsp/components/projectSummaryComponent.jsp	(working copy)
@@ -188,7 +188,7 @@
         <redback:ifAuthorized permission="continuum-build-group" resource="${projectGroupName}">
         <c:choose>
           <c:when test="${pageScope.project.state == 2}">
-            <ww:url id="releaseProjectUrl" action="releasePromptGoal" namespace="/">
+            <ww:url id="releaseProjectUrl" action="release2Input" namespace="/">
               <ww:param name="projectId" value="${project.id}"/>
             </ww:url>
             <ww:a href="%{releaseProjectUrl}">
@@ -201,7 +201,7 @@
         </c:choose>
         </redback:ifAuthorized>
         <redback:elseAuthorized>
-          <img src="<ww:url value='/images/releaseproject_disabled.gif' includeParams="none"/>" alt="<ww:text name="legend.release"/>" title="<ww:text name="legend.release"/>" border="0">
+          <img src="<ww:url value='/images/releaseproject_disabled.gif' includeParams="none"/>" alt="<ww:text name="delete"/>" title="<ww:text name="delete"/>" border="0">
         </redback:elseAuthorized>
       </ec:column>
       <ec:column property="deleteAction" title="&nbsp;" width="1%" sortable="false">
@@ -238,8 +238,9 @@
                            listKey="value" listValue="key" headerKey="-1" headerValue="%{getText('projectGroup.buildDefinition.label')}"
                            onchange="$('projectsForm').buildDefinitionId.value=$('buildDef').value" />
                 <input type="button" name="build-projects" value="<ww:text name="projectGroup.buildProjects"/>" onclick="$('projectsForm').methodToCall.value='build';document.forms.projectsForm.submit();" />
+                <input type="button" name="release-builds" value="<ww:text name="projectGroup.releaseBuilds"/>" onclick="document.forms.projectsForm.action='release2Input.action';document.forms.projectsForm.submit();" />
                 <input type="button" name="cancel-builds" value="<ww:text name="projectGroup.cancelBuilds"/>" onclick="document.forms.projectsForm.action='cancelBuilds.action';document.forms.projectsForm.submit();" />
-                <input type="button" name="delete-projects" value="<ww:text name="projectGroup.deleteProjects"/>" onclick="document.forms.projectsForm.methodToCall.value='confirmRemove';document.forms.projectsForm.submit();" />
+                <input type="button" name="delete-projects" value="<ww:text name="projectGroup.deleteProjects"/>" onclick="document.forms.projectsForm.methodToCall.value='remove';document.forms.projectsForm.submit();" />
               </redback:ifAuthorized>
             </td>
           </tr>
Index: continuum-webapp/src/main/webapp/WEB-INF/jsp/releaseProjectResult.jsp
===================================================================
--- continuum-webapp/src/main/webapp/WEB-INF/jsp/releaseProjectResult.jsp	(revision 0)
+++ continuum-webapp/src/main/webapp/WEB-INF/jsp/releaseProjectResult.jsp	(revision 0)
@@ -0,0 +1,43 @@
+<%--
+  ~ 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.
+  --%>
+
+<%@ taglib uri="/webwork" prefix="ww" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<html>
+  <ww:i18n name="localization.Continuum">
+    <head>
+      <title><ww:text name="releaseProject.page.title"/></title>
+      <ww:if test="!finished">
+        <meta http-equiv="refresh" content="10;url=release2ProjectResult.action?releaseId=<ww:property value="releaseId"/>&projectId=<ww:property value="projectId"/>"/>
+      </ww:if>
+    <ww:head />
+    </head>
+    <body>
+      <h2><ww:text name="releasePrepare.section.title"/></h2>
+      <ww:if test="finished">
+        <h3>Release finished</h3>
+      </ww:if>
+          <div class="axial">
+          <pre>
+          <ww:property value="result"/>
+          </pre>
+           </div>
+    </body>
+  </ww:i18n>
+</html>
Index: continuum-webapp/src/main/webapp/WEB-INF/jsp/releaseResultSummary.jsp
===================================================================
--- continuum-webapp/src/main/webapp/WEB-INF/jsp/releaseResultSummary.jsp	(revision 0)
+++ continuum-webapp/src/main/webapp/WEB-INF/jsp/releaseResultSummary.jsp	(revision 0)
@@ -0,0 +1,66 @@
+<%--
+  ~ 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.
+  --%>
+
+<%@ taglib uri="/webwork" prefix="ww" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<html>
+  <ww:i18n name="localization.Continuum">
+    <head>
+      <title><ww:text name="releaseProject.page.title"/></title>
+      <ww:if test="!finished">
+        <meta http-equiv="refresh" content="10;url=release2Result.action?releaseId=<ww:property value="descriptor.releaseId"/>"/>
+      </ww:if>
+    <ww:head />
+    </head>
+    <body>
+      <h2><ww:text name="releasePrepare.section.title"/></h2>
+      <ww:if test="finished">
+        <h3>Release finished</h3>
+      </ww:if>
+          <div class="axial">
+            <table border="1" cellspacing="2" cellpadding="3" width="100%">
+              <tr>
+                <th>Group</th>
+                <th>Artifact</th>
+                <th>Release version</th>
+                <th>Status</th>
+                <th>View result</th>
+              </tr>
+              <ww:iterator value="descriptor.projectsToRelease">
+              <tr>
+                <td><ww:property value="project.groupId"/></td>
+                <td><ww:property value="project.artifactId"/></td>
+                <td><ww:property value="releaseVersion"/></td>
+                <td><ww:property value="status"/></td>
+                <td>
+                <ww:url id="releaseProjectUrl" action="release2ProjectResult">
+                	<ww:param name="projectId">${project.id}</ww:param>
+                	<ww:param name="releaseId">${descriptor.releaseId}</ww:param>
+            	</ww:url>
+            	<ww:a href="%{releaseProjectUrl}">
+            	Result
+            	</ww:a>
+                </td>
+              </tr>
+              </ww:iterator>
+             </table>
+           </div>
+    </body>
+  </ww:i18n>
+</html>
Index: continuum-webapp/src/main/webapp/WEB-INF/jsp/releaseInput.jsp
===================================================================
--- continuum-webapp/src/main/webapp/WEB-INF/jsp/releaseInput.jsp	(revision 0)
+++ continuum-webapp/src/main/webapp/WEB-INF/jsp/releaseInput.jsp	(revision 0)
@@ -0,0 +1,200 @@
+<%--
+  ~ 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.
+  --%>
+
+<%@ taglib uri="/webwork" prefix="ww" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<script>
+  function toggleHidePrepareFields(field) {
+if (field.checked == true) { $$('.onlyPrepare').invoke('show') } else { $$('.onlyPrepare').invoke('hide') } ;
+  }  
+</script>
+
+<html>
+  <ww:i18n name="localization.Continuum">
+    <head>
+      <title><ww:text name="releaseProject.page.title"/></title>
+      <ww:head />
+    </head>
+    <body>
+      <h2><ww:text name="releasePrepare.section.title"/></h2>
+      <ww:form action="release2Execute.action" method="post">
+        <h3><ww:text name="releasePrepare.parameters"/></h3>
+        <input type="hidden" name="releaseId" value="<ww:property value="descriptor.releaseId"/>"/>
+        <input type="hidden" name="projectId" value="<ww:property value="projectId"/>"/>
+        <input type="hidden" name="projectGroupId" value="<ww:property value="projectGroupId"/>"/>
+        <div class="axial">
+          <table border="1" cellspacing="2" cellpadding="3" width="100%">
+            <tr>
+            	<td>
+            		<ww:checkbox id="prepareReleaseCC" theme="simple" name="prepareRelease" fieldValue="true" 
+            		onchange="toggleHidePrepareFields(this)"/>Prepare Release
+            	</td>
+            	<td>
+            		<ww:checkbox id="performReleaseCC" theme="simple" name="performRelease" fieldValue="true"/>Perform Release 
+            	</td>
+            </tr>
+            <tr class="b onlyPrepare">
+              <th>
+              	SCM Username
+              </th>
+              <td>
+            	<ww:textfield size="100" theme="simple" label="SCM Username" name="descriptor.username" required="true"/>
+              </td>
+            </tr>
+            <tr class="b onlyPrepare">
+              <th>
+              	SCM Password 
+              </th>
+              <td>
+            <ww:password size="100" theme="simple" name="descriptor.password" required="true"/>
+              </td>
+            </tr>
+         </table>
+       </div>
+       <h3>Default settings for the release</h3>
+       <div class="axial">
+          <table border="1" cellspacing="2" cellpadding="3" width="100%">
+            <tr>
+            <c:if test="${!empty(descriptor.releaseTagBase)}">
+              <ww:textfield label="SCM Tag Base" name="descriptor.releaseTagBase"/>
+            </c:if>
+            <tr/>
+            <ww:textfield label="Make the release from" name="descriptor.fromVersion" required="false"/>
+            <ww:select label="From Version Type" name="descriptor.versionType" list="#{'':'', 'Tag':'tag', 'Revision':'revision', 'Branch':'branch'}" required="false"/>
+            <!-- Hide the following field if not prepare -->
+            <tr  class="b onlyPrepare">
+              <th>
+                Branch to create (empty if release is made from a branch)
+              </th>
+              <td>
+                <ww:textfield theme="simple" name="descriptor.branchName" required="false" size="100" />
+              </td>
+            </tr>
+            <!-- TODO: Add possibility to change the default replacement for "." in version -->
+            <tr  class="b onlyPrepare">
+              <th>
+                SCM Tag
+              </th>
+              <td>
+                <ww:textfield size="100" theme="simple" name="descriptor.releaseTag" required="true"/>
+              </td>
+            </tr>
+            <tr  class="b onlyPrepare">
+              <th>
+                Release version
+              </th>
+              <td>
+                <ww:textfield size="100" theme="simple" name="descriptor.releaseVersion" required="true"/>
+              </td>
+            </tr>
+            <tr  class="b onlyPrepare">
+              <th>
+                Next SNAPSHOT Version 
+              </th>
+              <td>
+                <ww:textfield size="100" theme="simple" name="descriptor.nextDevelopmentVersion" required="true"/>
+              </td>
+            </tr>
+
+            <ww:select label="Profile" name="profileId" list="profiles" listValue="name" listKey="id"/>
+           </table>
+        </div>
+
+		<ww:if test="${!empty(descriptor.snapshotDependencies)}">
+        <h3>Dependencies version to use.</h3>
+          <div class="axial">
+            <table border="1" cellspacing="2" cellpadding="3" width="100%">
+              <tr>
+                <th>ArtifactId</th>
+                <th>Version</th>
+                <th><ww:text name="releasePrepare.releaseVersion"/></th>
+                <th><ww:text name="releasePrepare.nextDevelopmentVersion"/></th>
+              </tr>
+              <ww:iterator value="descriptor.snapshotDependencies">
+              <tr>
+                <input type="hidden" name="depGroupIds" value="<ww:property value="groupId"/>"/>
+                <input type="hidden" name="depArtifactIds" value="<ww:property value="artifactId"/>"/>
+              
+                <td><ww:property value="groupId"/></td>
+                <td><ww:property value="artifactId"/></td>
+                <td>
+                  <input type=text name="depReleaseVersions"
+                         value="<ww:property value="releaseVersion"/>">
+                </td>
+                <td>
+                  <input type=text name="depDevVersions"
+                         value="<ww:property value="nextDevelopmentVersion"/>">
+                </td>
+              </ww:iterator>
+			</table>
+		  </div>
+		</ww:if>
+
+        <h3>Projects to release. Let fields empty to use the defaults settings.</h3>
+        <!-- TODO: Add a link to hide all column not necesaries if using default settings -->
+          <div class="axial">
+            <table border="1" cellspacing="2" cellpadding="3" width="100%">
+              <tr>
+                <th>ArtifactId</th>
+                <th>Version</th>
+                <th class="projectDetail">Make the release from</th>
+                <th class="projectDetail">From Version Type</th>
+                <th class="projectDetail onlyPrepare">Branch to create</th>
+                <th class="projectDetail onlyPrepare">Scm tag</th>
+                <th class="projectDetail onlyPrepare"><ww:text name="releasePrepare.releaseVersion"/></th>
+                <th class="projectDetail onlyPrepare"><ww:text name="releasePrepare.nextDevelopmentVersion"/></th>
+              </tr>
+	          <ww:iterator value="descriptor.projectsToRelease">
+	          <input type="hidden" name="ids" value="<ww:property value="project.Id"/>"/>
+              <tr>
+                <td><ww:property value="project.artifactId"/></td>
+                <td><ww:property value="project.version"/></td>
+                <td class="projectDetail">
+                  <input type=text name="fromVersions"
+                         value="<ww:property value="fromVersion"/>">
+                </td>
+                <td class="projectDetail">
+                  <ww:select theme="simple" name="versionTypes" list="#{'':'', 'tag':'Tag', 'revision':'Revision', 'branch':'Branch'}" required="false"/>
+                </td>
+                <td class="projectDetail onlyPrepare">
+                  <input type=text name="branchNames" 
+						value="<ww:property value="branchName"/>">
+                </td>
+                <td class="projectDetail onlyPrepare">
+                  <input type=text name="releaseTags"
+                         value="<ww:property value="releaseTag"/>">
+                </td>
+                <td class="projectDetail onlyPrepare">
+                  <input type=text name="releaseVersions"
+                         value="<ww:property value="releaseVersion"/>">
+                </td>
+                <td class="projectDetail onlyPrepare">
+                  <input type=text name="devVersions"
+                         value="<ww:property value="nextDevelopmentVersion"/>">
+                </td>
+              </tr>
+              </ww:iterator>
+             </table>
+           </div>
+
+        <ww:submit/>
+      </ww:form>
+    </body>
+  </ww:i18n>
+</html>
Index: continuum-webapp/pom.xml
===================================================================
--- continuum-webapp/pom.xml	(revision 659128)
+++ continuum-webapp/pom.xml	(working copy)
@@ -284,6 +284,11 @@
       <groupId>org.apache.continuum</groupId>
       <artifactId>continuum-security</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.continuum</groupId>
+      <artifactId>continuum-release2</artifactId>
+    </dependency>
+
     <dependency> <!-- added since depMgt doesn't override imported dependencies -->
       <groupId>org.codehaus.plexus</groupId>
       <artifactId>plexus-utils</artifactId>

