add eclipse signing plugin
diff --git a/eclipse-signing-maven-plugin/README.txt b/eclipse-signing-maven-plugin/README.txt
new file mode 100644
index 0000000..77fc063
--- /dev/null
+++ b/eclipse-signing-maven-plugin/README.txt
@@ -0,0 +1,95 @@
+Example usage:
+
+  <profiles>
+    <profile>
+      <id>build-server</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.eclipse.dash.m4e</groupId>
+            <artifactId>eclipse-signing-maven-plugin</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <executions>
+              <!-- 
+              Pack the p2 repository.
+               -->
+              <execution>
+                <id>pack</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>pack</goal>
+                </goals>
+              </execution>
+              <!-- 
+              Sign the p2 repository
+              -->
+              <execution>
+                <id>sign</id>
+                <configuration>
+                  <signerInputDirectory>/home/data/httpd/download-staging.priv/rt/PROJECT</signerInputDirectory>
+                </configuration>
+                <phase>package</phase>
+                <goals>
+                  <goal>sign</goal>
+                </goals>
+              </execution>
+              <!-- 
+              Repack the p2 repository
+              -->
+              <execution>
+                <id>repack</id>
+                <configuration>
+                  <inputFile>${project.build.directory}/signed/site_assembly.zip</inputFile> <!-- this is output from signer mojo -->
+                </configuration>
+                <phase>package</phase>
+                <goals>
+                  <goal>pack</goal>
+                </goals>
+              </execution>
+              <!-- 
+              Signing and packing alters checksums so fix them
+              -->
+              <execution>
+                <id>fixCheckSums</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>fixCheckSums</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+          <!--
+          This is what I use to deploy a p2 repository someplace to test from before manually making active.        
+          -->
+          <plugin>
+              <artifactId>maven-antrun-plugin</artifactId>
+              <executions>
+                <execution>
+                  <id>deploy</id>
+                  <phase>install</phase>
+                  <goals>
+                    <goal>run</goal>
+                  </goals>
+                  <configuration>
+                    <tasks>
+                      <delete includeemptydirs="false">
+                        <fileset
+                          dir="/home/data/httpd/download.eclipse.org/jetty/updates/jetty-wtp/development">
+                          <include name="**" />
+                        </fileset>
+                      </delete>
+                      <copy includeemptydirs="false"
+                        todir="/home/data/httpd/download.eclipse.org/jetty/updates/jetty-wtp/development">
+                        <fileset dir="target/checksumFix">
+                          <include name="**" />
+                        </fileset>
+                      </copy>
+                    </tasks>
+                  </configuration>
+                </execution>
+              </executions>
+            </plugin>
+          </plugins>
+      </build>
+    </profile>
+  </profiles>
diff --git a/eclipse-signing-maven-plugin/pom.xml b/eclipse-signing-maven-plugin/pom.xml
new file mode 100644
index 0000000..b71411e
--- /dev/null
+++ b/eclipse-signing-maven-plugin/pom.xml
@@ -0,0 +1,105 @@
+<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>jetty-toolchain</artifactId>
+    <groupId>org.eclipse.jetty.toolchain</groupId>
+    <version>1.4</version>
+    <relativePath>../jetty-toolchain/pom.xml</relativePath>
+  </parent>
+
+  <groupId>org.eclipse.jetty.toolchain</groupId>
+  <artifactId>eclipse-signing-maven-plugin</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <name>Jetty :: Toolchain :: Eclipse Signing Maven Plugin</name>
+  <description>Plugin for signing code on the eclipse build servers.</description>
+  <packaging>maven-plugin</packaging>
+  <scm>
+    <connection>scm:git:http://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.toolchain.git</connection>
+    <developerConnection>scm:git:ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.toolchain.git</developerConnection>
+    <url>http://git.eclipse.org/c/jetty/org.eclipse.jetty.toolchain.git/tree/eclipse-signing-maven-plugin</url>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-project</artifactId>
+      <version>2.0.8</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+      <version>2.0.8</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-artifact</artifactId>
+      <version>2.0.8</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-tools-api</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-archiver</artifactId>
+      <version>2.0</version>
+    </dependency>
+     <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>3.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.ant</groupId>
+      <artifactId>ant</artifactId>
+      <version>1.8.2</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.mojo</groupId>
+      <artifactId>wagon-maven-plugin</artifactId>
+      <version>1.0-beta-3</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.9</version>
+        <!--configuration>
+          <skip>true</skip>
+        </configuration-->
+      </plugin>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-plugin-plugin</artifactId>
+        <version>2.8</version>
+        <executions>
+          <execution>
+            <id>exec-plugin-doc</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>helpmojo</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-plugin-plugin</artifactId>
+        <version>2.8</version>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
diff --git a/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/AbstractEclipseSigningMojo.java b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/AbstractEclipseSigningMojo.java
new file mode 100644
index 0000000..0c0082f
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/AbstractEclipseSigningMojo.java
@@ -0,0 +1,143 @@
+package org.eclipse.dash.m4e.eclipse.signing;
+
+//========================================================================
+//Copyright (c) 2010 Intalio, Inc.
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//The Eclipse Public License is available at 
+//http://www.eclipse.org/legal/epl-v10.html
+//The Apache License v2.0 is available at
+//http://www.opensource.org/licenses/apache2.0.php
+//You may elect to redistribute this code under either of these licenses. 
+//========================================================================
+
+import java.io.File;
+import java.net.InetAddress;
+
+import org.apache.maven.artifact.manager.WagonManager;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.wagon.CommandExecutor;
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.mojo.wagon.shared.WagonUtils;
+
+public abstract class AbstractEclipseSigningMojo extends AbstractMojo
+{
+    /**
+     * @component
+     */
+    protected WagonManager wagonManager;
+
+    /**
+     * The current user system settings for use in Maven.
+     * 
+     * @parameter expression="${settings}"
+     * @readonly
+     */
+    protected Settings settings;
+
+    /**
+     * protocol for the wagon connection
+     * 
+     * Example: scp://
+     * 
+     * @parameter
+     */
+    protected String wagonProtocol;
+
+    /**
+     * host portion of the wagon connection
+     * 
+     * Example: build.eclipse.org
+     * 
+     * @parameter
+     */
+    protected String wagonHost;
+
+    /**
+     * path portion of the wagon connection
+     * 
+     * Example: /home/data/users/jmcconnell
+     * 
+     * @parameter
+     */
+    protected String wagonPath;
+
+    /**
+     * @parameter
+     */
+    protected String serverId;
+
+    /**
+     * @parameter default-value="900000";
+     * @required
+     */
+    protected int wagonTimeout;
+
+    /**
+     * 
+     * @return
+     * @throws Exception
+     */
+    protected boolean runningOnBuildMachine() throws Exception
+    {
+        if (InetAddress.getLocalHost().getHostName().equals("build.eclipse.org"))
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    protected String adjustToWagonPath(String location)
+    {
+        return wagonPath + File.separator + location;
+    }
+
+    protected String getWagonUrl() throws Exception
+    {
+        if (wagonProtocol == null || wagonHost == null || wagonPath == null)
+        {
+            throw new IllegalArgumentException("missing wagon configuration bits, unable to operate remotely");
+        }
+
+        if (runningOnBuildMachine())
+        {
+            return wagonProtocol + wagonPath;
+        }
+
+        return wagonProtocol + wagonHost + wagonPath;
+    }
+
+    protected Wagon createWagon(String id, String url) throws MojoExecutionException
+    {
+        try
+        {
+            return WagonUtils.createWagon(id,url,wagonManager,settings,this.getLog());
+        }
+        catch (Exception e)
+        {
+            throw new MojoExecutionException("Unable to create a Wagon instance for " + url,e);
+        }
+
+    }
+
+    protected CommandExecutor getCommandExecutor(Wagon wagon) throws Exception
+    {
+        if (!(wagon instanceof CommandExecutor))
+        {
+            throw new MojoExecutionException("unable to operate remotely, requires wagon capable of invoking commands");
+        }
+
+        CommandExecutor exec = (CommandExecutor)wagon;
+
+        exec.setTimeout(wagonTimeout);
+
+        return exec;
+    }
+}
diff --git a/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/ChecksumMojo.java b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/ChecksumMojo.java
new file mode 100644
index 0000000..26ab4b8
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/ChecksumMojo.java
@@ -0,0 +1,482 @@
+package org.eclipse.dash.m4e.eclipse.signing;
+
+//========================================================================
+//Copyright (c) 2010 Intalio, Inc.
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//The Eclipse Public License is available at 
+//http://www.eclipse.org/legal/epl-v10.html
+//The Apache License v2.0 is available at
+//http://www.opensource.org/licenses/apache2.0.php
+//You may elect to redistribute this code under either of these licenses. 
+//========================================================================
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.codehaus.plexus.archiver.zip.ZipArchiver;
+import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
+import org.codehaus.plexus.util.FileUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * This plugin walks through a p2 repository and repairs the artifacts.xml.
+ * <br/>
+ * It also insert the property <code>&lt;property name='publishPackFilesAsSiblings' value='true'/&gt;</code>
+ * and the mapping rules if they were not present already:
+ * <br/>
+ * <code>&lt;rule filter='(&amp; (classifier=osgi.bundle) (format=packed))'
+ *    output='${repoUrl}/plugins/${id}_${version}.jar.pack.gz'/&gt;</code>
+ * <br/><code>&lt;rule filter='(&amp; (classifier=org.eclipse.update.feature) (format=packed))'
+ *    output='${repoUrl}/features/${id}_${version}.jar.pack.gz'/&gt;</code>
+ * @goal fixCheckSums
+ * @phase package
+ * @description updates the md5 checksum and file size
+ */
+public class ChecksumMojo extends AbstractEclipseSigningMojo
+{
+    /**
+     * zip file to get checksum'ed
+     * 
+     * @parameter default-value="${project.build.directory}/packed/site_assembly.zip"
+     * @required
+     */
+    protected String inputFile;
+
+    /**
+     * zip file to get checksum'ed
+     * 
+     * @parameter default-value="${project.build.directory}/fixed/site_assembly.zip"
+     * @required
+     */
+    protected String outputFile;
+
+    /**
+     * zip file to get checksum'ed
+     * 
+     * @parameter default-value="${project.build.directory}/checksumFix"
+     * @required
+     */
+    protected String unzipDir;
+
+    /**
+     * unpack path for artifact
+     * 
+     * @parameter default-value="/"
+     * @required
+     */
+    protected String unpackPath;
+
+    /**
+     * checksum file
+     * 
+     * @parameter default-value="${project.build.directory}/checksumFix/artifacts.xml
+     * @required
+     */
+    protected String artifactsXml;
+
+    public void execute() throws MojoExecutionException, MojoFailureException
+    {
+        try
+        {
+
+            if (!FileUtils.fileExists(unzipDir))
+            {
+                info("creating directory to hold unzipped artifact");
+                FileUtils.mkdir(unzipDir);
+            }
+
+            if (!FileUtils.fileExists(FileUtils.dirname(outputFile)))
+            {
+                info("creating directory to hold output");
+                FileUtils.mkdir(FileUtils.dirname(outputFile));
+            }
+
+            ZipUnArchiver unzipper = new ZipUnArchiver(new File(inputFile));
+            unzipper.extract("",new File(unzipDir));
+
+            ZipUnArchiver unzipper2 = new ZipUnArchiver(new File(unzipDir + "/artifacts.jar"));
+            unzipper2.extract("",new File(unzipDir));
+
+            FileUtils.fileDelete(unzipDir + "/artifacts.jar.pack.gz");
+            FileUtils.fileDelete(unzipDir + "/content.jar.pack.gz");
+            
+            insertPropertyAndMappingRules();
+
+            @SuppressWarnings("unchecked")
+            List<String> files = FileUtils.getFileNames(new File(unzipDir),"**/*.jar","",true);
+
+            for (Iterator<String> i = files.iterator(); i.hasNext();)
+            {
+                String filename = i.next();
+                info("Processing: " + filename);
+                if (filename.endsWith("artifacts.jar"))
+                {
+                    continue;
+                }
+                else if (filename.endsWith("content.jar"))
+                {
+                    continue;
+                }
+                else
+                {
+                    update(filename);
+                }
+            }
+
+            FileUtils.fileDelete(unzipDir + "/artifacts.jar");
+
+            ZipArchiver zipper = new ZipArchiver();
+            zipper.addFile(new File(unzipDir + "/artifacts.xml"),"artifacts.xml");
+            // zipper.addDirectory(new File(unzipDir));
+            zipper.setDestFile(new File(unzipDir + "/artifacts.jar"));
+            zipper.createArchive();
+
+            FileUtils.fileDelete(unzipDir + "/artifacts.xml");
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+
+    }
+
+    private void update(String plugin)
+    {
+        try
+        {
+            /*
+             * some people have features the same as plugins features so we need to tweak the xpath
+             */
+            boolean isPlugin = plugin.contains("/plugins/");
+            
+            String pluginFile = FileUtils.basename(plugin,".jar");
+
+            Pattern p = Pattern.compile("_\\d*\\.");
+        	
+        	String[] bits = p.split(pluginFile);
+        	
+        	//System.out.println(file.substring(0, bits[0].length()) + " / " + file.substring(bits[0].length() + 1 , file.length()));
+        	            
+            int versionSplitUnderscore = bits[0].length();
+            
+            String[] artifactBits = new String[2];
+
+            artifactBits[0] = pluginFile.substring(0,versionSplitUnderscore);
+            artifactBits[1] = pluginFile.substring(versionSplitUnderscore + 1, pluginFile.length());
+            
+            getLog().info(" Artifact: " + artifactBits[0] + " / Version: " + artifactBits[1] + " / isPlugin: " + isPlugin );
+
+            File inFile = new File(plugin);
+            String inFileSize = Long.toString(inFile.length());
+
+            int count = 0;
+            byte[] buffer = new byte[1024 * 16];
+            InputStream in = new FileInputStream(inFile);
+            MessageDigest md = MessageDigest.getInstance("MD5");
+
+            while ((count = in.read(buffer)) > 0)
+            {
+                md.update(buffer,0,count);
+            }
+            in.close();
+
+            String inFileMD5 = convert(md.digest());// (new BigInteger(1, md.digest())).toString(16);
+
+            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+            Document document = builder.parse(new File(artifactsXml));
+
+            String expr;
+            XPath xpath = XPathFactory.newInstance().newXPath();
+
+            if ( isPlugin )
+            {
+                expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='osgi.bundle']/properties//property[@name='artifact.size']/@value";
+            }
+            else
+            {
+                expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='org.eclipse.update.feature']/properties//property[@name='artifact.size']/@value";
+            }
+            Node artifactSize = (Node)xpath.evaluate(expr,document,XPathConstants.NODE);
+            if (artifactSize != null)
+            {
+                artifactSize.setNodeValue(inFileSize);
+            }
+
+            if (isPlugin)
+            {
+                expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='osgi.bundle']/properties//property[@name='download.size']/@value";
+            }
+            else
+            {
+                expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='org.eclipse.update.feature']/properties//property[@name='download.size']/@value";   
+            }
+            
+            Node downloadSize = (Node)xpath.evaluate(expr,document,XPathConstants.NODE);
+            if (downloadSize != null)
+            {
+                downloadSize.setNodeValue(inFileSize);
+            }
+
+            if ( isPlugin )
+            {
+                expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='osgi.bundle']/properties//property[@name='download.md5']/@value";
+            }
+            else
+            {
+                expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='org.eclipse.update.feature']/properties//property[@name='download.md5']/@value";
+            }
+            Node downloadMD5 = (Node)xpath.evaluate(expr,document,XPathConstants.NODE);
+            if (downloadMD5 != null)
+            {
+                downloadMD5.setNodeValue(inFileMD5);
+            }
+
+            if (FileUtils.fileExists(plugin + ".pack.gz"))
+            {
+                File packFile = new File(plugin + ".pack.gz");
+                String packFileSize = Long.toString(packFile.length());
+
+                expr = "/repository/artifacts";// //artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "']";
+                Node normal = (Node)xpath.evaluate(expr,document,XPathConstants.NODE);
+                Element packed = document.createElement("artifact");
+
+                packed.setAttribute("classifier", isPlugin ? "osgi.bundle" : "org.eclipse.update.feature");
+                packed.setAttribute("id",artifactBits[0]);
+                packed.setAttribute("version",artifactBits[1]);
+
+                Element processing = document.createElement("processing");
+                processing.setAttribute("size","1");
+                packed.appendChild(processing);
+
+                Element step = document.createElement("step");
+                step.setAttribute("id","org.eclipse.equinox.p2.processing.Pack200Unpacker");
+                step.setAttribute("required","true");
+                processing.appendChild(step);
+
+                Element properties = document.createElement("properties");
+                properties.setAttribute("size","3");
+                packed.appendChild(properties);
+
+                Element prop1 = document.createElement("property");
+                prop1.setAttribute("name","artifact.size");
+                prop1.setAttribute("value",inFileSize);
+                properties.appendChild(prop1);
+
+                Element prop2 = document.createElement("property");
+                prop2.setAttribute("name","download.size");
+                prop2.setAttribute("value",packFileSize);
+                properties.appendChild(prop2);
+
+                Element prop3 = document.createElement("property");
+                prop3.setAttribute("name","format");
+                prop3.setAttribute("value","packed");
+                properties.appendChild(prop3);
+
+                normal.appendChild(packed);
+
+            }
+
+            Transformer txformer = TransformerFactory.newInstance().newTransformer();
+            DOMSource src = new DOMSource(document);
+            StreamResult res = new StreamResult(artifactsXml);
+            txformer.transform(src,res);
+        }
+        catch (Exception e)
+        {
+            getLog().error(e);
+        }
+    }
+    
+    /**
+     * Creates the extra property and mapping rules for the pack.gz
+     */
+    protected void insertPropertyAndMappingRules()
+    {
+    	try
+    	{
+	        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+	        Document document = builder.parse(new File(artifactsXml));
+	        
+	        boolean documentWasModified = false;
+	
+	        {
+	        //<property name='publishPackFilesAsSiblings' value='true'/>
+	        String selectPublishPackfilesAsSiblings = "/repository/properties/property[@name='publishPackFilesAsSiblings']";
+	        XPath xpath = XPathFactory.newInstance().newXPath();
+	        Element propertyEl = (Element)xpath.evaluate(selectPublishPackfilesAsSiblings,document,XPathConstants.NODE);
+
+	        String selectProperties = "/repository/properties";
+	        xpath = XPathFactory.newInstance().newXPath();
+	        Element propertiesEl = (Element)xpath.evaluate(selectProperties,document,XPathConstants.NODE);
+	        if (propertiesEl == null)
+	        {
+	        	throw new IllegalArgumentException("The artifacts.xml document must have a /repository/properties element.");
+	        }
+
+	        if (propertyEl == null)
+    		{
+		        Element publishPackElem = document.createElement("property");
+		        publishPackElem.setAttribute("name", "publishPackFilesAsSiblings");
+		        publishPackElem.setAttribute("value", "true");
+		        propertiesEl.appendChild(publishPackElem);
+		        documentWasModified = true;
+    		}
+	        else
+	        {
+	        	if (!"true".equals(propertyEl.getAttribute("value")))
+	        	{
+	        		propertyEl.setAttribute("value", "true");
+	        		documentWasModified = true;
+	        	}
+	        }
+	        
+	        //update the number of properties attribute
+	        if (documentWasModified)
+	        {
+	        	int size = propertiesEl.getElementsByTagName("property").getLength();
+	        	propertiesEl.setAttribute("size", String.valueOf(size));
+	        }
+	        }//end of properties processor
+	        
+	        {
+	        //<rule filter='(&amp; (classifier=osgi.bundle) (format=packed))'
+	        //      output='${repoUrl}/plugins/${id}_${version}.jar.pack.gz'/>
+	        //<rule filter='(&amp; (classifier=org.eclipse.update.feature) (format=packed))'
+	        //      output='${repoUrl}/features/${id}_${version}.jar.pack.gz'/>
+	        String selectMappings = "/repository/mappings";
+	        XPath xpath = XPathFactory.newInstance().newXPath();
+	        Element mappingsEl = (Element)xpath.evaluate(selectMappings,document,XPathConstants.NODE);
+	        if (mappingsEl == null)
+	        {
+	        	throw new IllegalArgumentException("The artifacts.xml document must have a /repository/mappings element.");
+	        }
+	        
+	        //Just iterate over the rules elements and look at the value of the attributes.
+	        boolean foundPackedBundleFilter = false;
+	        boolean foundPackedFeatureFilter = false;
+	        NodeList nl = mappingsEl.getChildNodes();
+	        for (int i = 0; i < nl.getLength(); i++)
+	        {
+	        	Node c = nl.item(i);
+	        	if (c.getNodeType() == Node.ELEMENT_NODE)
+	        	{
+	        		Element rule = (Element)c;
+	        		String filter = rule.getAttribute("filter");
+	        		if (filter.indexOf("format=packed") != -1)
+	        		{
+	        			if (filter.indexOf("classifier=osgi.bundle") != -1)
+	        			{
+	        				foundPackedBundleFilter = true;
+	        			}
+	        			else if (filter.indexOf("classifier=org.eclipse.update.feature") != -1)
+	        			{
+	        				foundPackedFeatureFilter = true;
+	        			}
+	        			if (foundPackedBundleFilter && foundPackedFeatureFilter)
+	        			{
+	        				break;
+	        			}
+	        		}
+	        	}
+	        }
+	        if (!foundPackedBundleFilter)
+	        {
+		        Element ruleElem = document.createElement("rule");
+		        ruleElem.setAttribute("filter", "(& (classifier=osgi.bundle) (format=packed))");
+		        ruleElem.setAttribute("output", "${repoUrl}/plugins/${id}_${version}.jar.pack.gz");
+		        // Bug 356931 format=packed must be first rule in mappings
+		        Node firstRule = mappingsEl.getFirstChild();
+		        mappingsEl.insertBefore(ruleElem, firstRule);
+		        documentWasModified = true;
+	        }
+	        if (!foundPackedFeatureFilter)
+	        {
+		        Element ruleElem = document.createElement("rule");
+		        ruleElem.setAttribute("filter", "(& (classifier=org.eclipse.update.feature) (format=packed))");
+		        ruleElem.setAttribute("output", "${repoUrl}/features/${id}_${version}.jar.pack.gz");
+		        // Bug 356931 format=packed must be first rule in mappings
+		        Node firstRule = mappingsEl.getFirstChild();
+		        mappingsEl.insertBefore(ruleElem, firstRule);
+
+		        documentWasModified = true;
+	        }
+	        //update the number of properties attribute
+	        if (!foundPackedFeatureFilter || !foundPackedBundleFilter)
+	        {
+	        	int size = mappingsEl.getElementsByTagName("rule").getLength();
+	        	mappingsEl.setAttribute("size", String.valueOf(size));
+	        }
+	        
+	        }//end of rules processor
+	        
+	        if (documentWasModified)
+	        {
+	            Transformer txformer = TransformerFactory.newInstance().newTransformer();
+	            DOMSource src = new DOMSource(document);
+	            StreamResult res = new StreamResult(artifactsXml);
+	            txformer.transform(src,res);
+	        }
+        }
+        catch (Exception e)
+        {
+            getLog().error(e);
+        }
+        
+    }
+
+    private String convert(byte[] bytes)
+    {
+        StringBuffer sb = new StringBuffer();
+
+        for (int i = 0; i < bytes.length; ++i)
+        {
+            sb.append(Character.forDigit((bytes[i] >> 4) & 0xf,16));
+            sb.append(Character.forDigit(bytes[i] & 0xf,16));
+        }
+        return sb.toString();
+    }
+
+    private void info(String log)
+    {
+        getLog().info("[FIX] " + log);
+    }
+
+    public static void main(String[] args ) throws Exception
+    {
+    	String file = "org.eclipse.equinox.server.core_1.1.1.R37x_v20110907-7K7TFBYDzbeA3ypK_98cDL15A4A";
+    	Pattern p = Pattern.compile("_\\d");
+    	
+    	String[] bits = p.split(file);
+    	
+    	System.out.println(file.substring(0, bits[0].length()) + " / " + file.substring(bits[0].length() + 1 , file.length()));
+    	
+    	
+    	
+    	
+    }
+    
+    
+}
diff --git a/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/PackMojo.java b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/PackMojo.java
new file mode 100644
index 0000000..bddae4c
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/PackMojo.java
@@ -0,0 +1,348 @@
+package org.eclipse.dash.m4e.eclipse.signing;
+
+//========================================================================
+//Copyright (c) 2010 Intalio, Inc.
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//The Eclipse Public License is available at 
+//http://www.eclipse.org/legal/epl-v10.html
+//The Apache License v2.0 is available at
+//http://www.opensource.org/licenses/apache2.0.php
+//You may elect to redistribute this code under either of these licenses. 
+//========================================================================
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.zip.ZipArchiver;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+
+/**
+ * 
+ * @goal pack
+ * @phase package
+ * @description runs the eclipse packing process
+ */
+public class PackMojo extends AbstractEclipseSigningMojo
+{
+    private static final String __PACK_JAR = "org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100503a.jar";
+
+    private static final String __PACK_PROPERTIES = "pack.properties";
+
+    /**
+     * zip file to be packed
+     * 
+     * @parameter default-value= "${project.build.directory}/site_assembly.zip"
+     * @required
+     */
+    protected String inputFile;
+
+    /**
+     * directory monitor for artifact
+     * 
+     * @parameter default-value="${project.build.directory}/packed"
+     * @required
+     */
+    protected String packedOutputDirectory;
+
+    /**
+     * directory for required bits
+     * 
+     * @parameter default-value="${project.build.directory}/pack-stage"
+     * @required
+     */
+    protected String stagingDirectory;
+
+    /**
+     * location of pack200
+     * 
+     * @parameter default-value="/shared/common/jdk-1.5.0-22.x86_64/bin"
+     * @required
+     */
+    protected String pack200;
+
+    /**
+     * @parameter default-value="/usr/local/bin/java"
+     * @required
+     */
+    protected String javaExecutable;
+
+    /** @parameter expression="${project}" */
+    protected MavenProject project;
+
+    /**
+     * List of patterns for a directory scanner to select the jars that must not be packed.
+     * 
+     * @parameter
+     */
+    protected String packExclude;
+
+    /**
+     * when true, remove the pack.gz files to make sure no confusion will happen later.
+     * 
+     * @parameter default-value="false"
+     * @required
+     */
+    protected boolean conditionOnly;
+
+    public void execute() throws MojoExecutionException, MojoFailureException
+    {
+        if (!FileUtils.fileExists(inputFile))
+        {
+            throw new MojoFailureException("file to pack does not exist! -> " + inputFile);
+        }
+
+        if (!FileUtils.fileExists(packedOutputDirectory))
+        {
+            info("creating directory to hold packed output");
+            FileUtils.mkdir(packedOutputDirectory);
+        }
+
+        if (!FileUtils.fileExists(stagingDirectory))
+        {
+            info("creating directory to hold pack staging bits");
+            FileUtils.mkdir(stagingDirectory);
+        }
+
+        if (new File(inputFile).isDirectory())
+        {
+
+            setupPackProperties(new File(inputFile),null);
+
+            ZipArchiver zipper = new ZipArchiver();
+            File destFile = new File(project.getBuild().getDirectory(),"repository-zipped/" + project.getArtifactId() + "-" + project.getVersion() + ".zip");
+
+            try
+            {
+                destFile.getParentFile().mkdirs();
+                zipper.addDirectory(new File(inputFile));
+                zipper.setDestFile(destFile);
+                zipper.createArchive();
+            }
+            catch (Exception e)
+            {
+                throw new MojoExecutionException("Error packing product",e);
+            }
+            inputFile = destFile.getAbsolutePath();
+        }
+
+        try
+        {
+            packLocally();
+        }
+        catch (Exception e)
+        {
+            throw new MojoExecutionException(e.getMessage(),e);
+        }
+
+    }
+
+    /**
+     * Some jars must not go through the packer. This is controlled via the pack.properties file at the root of the directory where jars are packed.
+     * <p>
+     * When the pack.properties file is copied, update the property pack.excludes for example:<br/>
+     * pack.excludes=plugins/com.ibm.icu.base_3.6.1.v20070417.jar,plugins/com. ibm.icu_3.6.1.v20070417.jar,plugins/com.jcraft.jsch_0.1.31.jar
+     * </p>
+     * <p>
+     * More doc here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=178723
+     * </p>
+     */
+    @SuppressWarnings("deprecation")
+    private void setupPackProperties(File targetRepo, File packPropertiesSource) throws MojoExecutionException
+    {
+        // pack.excludes=com.ibm.icu.base_3.6.1.v20070417.jar,com.ibm.icu_3.6.1.v20070417.jar,com.jcraft.jsch_0.1.31.jar
+        Properties props = new Properties();
+        InputStream inStream = null;
+        OutputStream outStream = null;
+        try
+        {
+            if (packPropertiesSource != null && packPropertiesSource.canRead())
+            {
+                props.load(inStream);
+            }
+            else
+            {
+                // put the default property:
+                props.put("pack200.default.args","-E4");
+            }
+            props.put("pack.excludes",getPackExcluded(targetRepo).toString());
+
+            File out = new File(targetRepo,__PACK_PROPERTIES);
+            if (!out.exists())
+                out.createNewFile();
+            outStream = new FileOutputStream(out);
+            props.save(outStream,"Pack.properties generated by the packmojo");
+        }
+        catch (IOException ioe)
+        {
+            throw new MojoExecutionException("Unable to setup the pack.properties file",ioe);
+        }
+        finally
+        {
+            if (inStream != null)
+            {
+                try
+                {
+                    inStream.close();
+                }
+                catch (IOException ioe)
+                {
+                }
+            }
+            if (outStream != null)
+            {
+                try
+                {
+                    outStream.close();
+                }
+                catch (IOException ioe)
+                {
+                }
+            }
+        }
+    }
+
+    private String getPackExcluded(File targetRepoDirectory)
+    {
+        StringBuilder patterns = new StringBuilder("artifacts.jar,content.jar");
+        if (packExclude != null)
+        {
+            patterns.append("," + packExclude);
+        }
+        DirectoryScanner scanner = new DirectoryScanner();
+        scanner.setBasedir(targetRepoDirectory);
+        StringTokenizer tokenizer = new StringTokenizer(patterns.toString(),", \r\n\t",false);
+        String[] incls = new String[tokenizer.countTokens()];
+        int i = 0;
+        while (tokenizer.hasMoreTokens())
+        {
+            String tok = tokenizer.nextToken();
+            incls[i] = tok;
+            i++;
+        }
+        scanner.setIncludes(incls);
+        scanner.scan();
+        String[] includedFiles = scanner.getIncludedFiles();
+        StringBuilder excluded = null;
+        for (String incl : includedFiles)
+        {
+            incl = incl.replace('\\','/');
+            if (excluded == null)
+            {
+                excluded = new StringBuilder(incl);
+            }
+            else
+            {
+                excluded.append("," + incl);
+            }
+        }
+        return excluded.toString();
+    }
+
+
+    private String[] generatePackExecuteString(String jarPackerLoc, String toPack, String outputDirectory)
+    {
+
+        // http://wiki.eclipse.org/index.php/Pack200
+        /*
+         * 3.5 style: java -cp org.eclipse.equinox.p2.jarprocessor_1.0.100.v20090520-1905.jar org.eclipse.equinox.internal.p2.jarprocessor.Main -processAll
+         * -repack -sign signing-script.sh -outputDir ./out eclipse-SDK.zip 3.6 syle: java -jar org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100123-1019.jar
+         * -processAll -repack -sign signing-script.sh -pack -outputDir ./out eclipse-SDK.zip
+         */
+        return new String[]
+        { "-Dorg.eclipse.update.jarprocessor.pack200=" + pack200, "-jar", jarPackerLoc, "-processAll", "-pack", "-repack",
+                // this does not work with the new version of the jar processor
+                /*
+                 * "-f", FileUtils.dirname(jarPackerLoc) + File.separator + "pack.properties",
+                 */
+                "-verbose", "-outputDir", outputDirectory, toPack };
+
+    }
+
+    private void positionPackJarForExecution() throws MojoExecutionException
+    {
+        info("getting jar packer into position");
+
+        URL jarPacker = this.getClass().getClassLoader().getResource(__PACK_JAR);
+        URL jarProperties = this.getClass().getClassLoader().getResource(__PACK_PROPERTIES);
+        try
+        {
+            FileUtils.copyURLToFile(jarPacker,new File(stagingDirectory + File.separator + __PACK_JAR));
+            FileUtils.copyURLToFile(jarProperties,new File(stagingDirectory + File.separator + __PACK_PROPERTIES));
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+            throw new MojoExecutionException("unable to position jar packer",e);
+        }
+    }
+
+    private void packLocally() throws Exception
+    {
+
+        if (!FileUtils.fileExists(packedOutputDirectory))
+        {
+            info("creating directory to hold packed output");
+            FileUtils.mkdir(packedOutputDirectory);
+        }
+
+        try
+        {
+            String packTempDirectory = stagingDirectory + File.separator + UUID.randomUUID().toString();
+
+            FileUtils.mkdir(packTempDirectory);
+
+            FileUtils.copyFileToDirectory(inputFile,packTempDirectory);
+
+            CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer();
+            CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
+
+            positionPackJarForExecution();
+
+            Commandline pack = new Commandline();
+            pack.setWorkingDirectory(FileUtils.dirname(packTempDirectory));
+            pack.setExecutable(javaExecutable);
+            pack.addArguments(generatePackExecuteString(stagingDirectory + "/" + __PACK_JAR,inputFile,packedOutputDirectory));
+
+            info("executing pack200, output at end of execution : " + pack);
+            CommandLineUtils.executeCommandLine(pack,out,err);
+
+            String packErrput = IOUtil.toString(new StringReader(err.getOutput()));
+            String packOutput = IOUtil.toString(new StringReader(out.getOutput()));
+
+            info("pack200 output:\n" + packOutput);
+            if (packErrput != null || !"".equals(packErrput))
+            {
+                getLog().error(packErrput);
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            getLog().error(e);
+        }
+    }
+
+    private void info(String log)
+    {
+        getLog().info("[PACK] " + log);
+    }
+
+}
diff --git a/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/RepackMojo.java b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/RepackMojo.java
new file mode 100644
index 0000000..fbd06e3
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/RepackMojo.java
@@ -0,0 +1,350 @@
+package org.eclipse.dash.m4e.eclipse.signing;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.zip.ZipArchiver;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+
+//========================================================================
+//Copyright (c) 2010 Intalio, Inc.
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//The Eclipse Public License is available at 
+//http://www.eclipse.org/legal/epl-v10.html
+//The Apache License v2.0 is available at
+//http://www.opensource.org/licenses/apache2.0.php
+//You may elect to redistribute this code under either of these licenses. 
+//========================================================================
+
+
+/**
+ * 
+ * @goal repack
+ * @phase package
+ * @description runs the eclipse packing process
+ */
+public class RepackMojo extends AbstractEclipseSigningMojo
+{
+    
+    private static final String __PACK_JAR = "org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100503a.jar";
+
+    private static final String __PACK_PROPERTIES = "pack.properties";
+  
+    /**
+     * zip file to be packed
+     * 
+     * @parameter default-value= "${project.build.directory}/signed/site_assembly.zip"
+     * @required
+     */
+    protected String inputFile;  
+
+    /**
+     * directory monitor for artifact
+     * 
+     * @parameter default-value="${project.build.directory}/packed"
+     * @required
+     */
+    protected String packedOutputDirectory;
+
+    /**
+     * directory for required bits
+     * 
+     * @parameter default-value="${project.build.directory}/pack-stage"
+     * @required
+     */
+    protected String stagingDirectory;
+
+    /**
+     * location of pack200
+     * 
+     * @parameter default-value="/shared/common/jdk-1.5.0-22.x86_64/bin"
+     * @required
+     */
+    protected String pack200;
+
+    /**
+     * @parameter default-value="/usr/local/bin/java"
+     * @required
+     */
+    protected String javaExecutable;
+
+    /** @parameter expression="${project}" */
+    protected MavenProject project;
+
+    /**
+     * List of patterns for a directory scanner to select the jars that must not be packed.
+     * 
+     * @parameter
+     */
+    protected String packExclude;
+
+    /**
+     * when true, remove the pack.gz files to make sure no confusion will happen later.
+     * 
+     * @parameter default-value="false"
+     * @required
+     */
+    protected boolean conditionOnly;
+
+    public void execute() throws MojoExecutionException, MojoFailureException
+    {
+        if (!FileUtils.fileExists(inputFile))
+        {
+            throw new MojoFailureException("file to pack does not exist! -> " + inputFile);
+        }
+
+        if (!FileUtils.fileExists(packedOutputDirectory))
+        {
+            info("creating directory to hold packed output");
+            FileUtils.mkdir(packedOutputDirectory);
+        }
+
+        if (!FileUtils.fileExists(stagingDirectory))
+        {
+            info("creating directory to hold pack staging bits");
+            FileUtils.mkdir(stagingDirectory);
+        }
+
+        if (new File(inputFile).isDirectory())
+        {
+
+            setupPackProperties(new File(inputFile),null);
+
+            ZipArchiver zipper = new ZipArchiver();
+            File destFile = new File(project.getBuild().getDirectory(),"repository-zipped/" + project.getArtifactId() + "-" + project.getVersion() + ".zip");
+
+            try
+            {
+                destFile.getParentFile().mkdirs();
+                zipper.addDirectory(new File(inputFile));
+                zipper.setDestFile(destFile);
+                zipper.createArchive();
+            }
+            catch (Exception e)
+            {
+                throw new MojoExecutionException("Error packing product",e);
+            }
+            inputFile = destFile.getAbsolutePath();
+        }
+
+        try
+        {
+            packLocally();
+        }
+        catch (Exception e)
+        {
+            throw new MojoExecutionException(e.getMessage(),e);
+        }
+
+    }
+
+    /**
+     * Some jars must not go through the packer. This is controlled via the pack.properties file at the root of the directory where jars are packed.
+     * <p>
+     * When the pack.properties file is copied, update the property pack.excludes for example:<br/>
+     * pack.excludes=plugins/com.ibm.icu.base_3.6.1.v20070417.jar,plugins/com. ibm.icu_3.6.1.v20070417.jar,plugins/com.jcraft.jsch_0.1.31.jar
+     * </p>
+     * <p>
+     * More doc here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=178723
+     * </p>
+     */
+    @SuppressWarnings("deprecation")
+    private void setupPackProperties(File targetRepo, File packPropertiesSource) throws MojoExecutionException
+    {
+        // pack.excludes=com.ibm.icu.base_3.6.1.v20070417.jar,com.ibm.icu_3.6.1.v20070417.jar,com.jcraft.jsch_0.1.31.jar
+        Properties props = new Properties();
+        InputStream inStream = null;
+        OutputStream outStream = null;
+        try
+        {
+            if (packPropertiesSource != null && packPropertiesSource.canRead())
+            {
+                props.load(inStream);
+            }
+            else
+            {
+                // put the default property:
+                props.put("pack200.default.args","-E4");
+            }
+            props.put("pack.excludes",getPackExcluded(targetRepo).toString());
+
+            File out = new File(targetRepo,__PACK_PROPERTIES);
+            if (!out.exists())
+                out.createNewFile();
+            outStream = new FileOutputStream(out);
+            props.save(outStream,"Pack.properties generated by the packmojo");
+        }
+        catch (IOException ioe)
+        {
+            throw new MojoExecutionException("Unable to setup the pack.properties file",ioe);
+        }
+        finally
+        {
+            if (inStream != null)
+            {
+                try
+                {
+                    inStream.close();
+                }
+                catch (IOException ioe)
+                {
+                }
+            }
+            if (outStream != null)
+            {
+                try
+                {
+                    outStream.close();
+                }
+                catch (IOException ioe)
+                {
+                }
+            }
+        }
+    }
+
+    private String getPackExcluded(File targetRepoDirectory)
+    {
+        StringBuilder patterns = new StringBuilder("artifacts.jar,content.jar");
+        if (packExclude != null)
+        {
+            patterns.append("," + packExclude);
+        }
+        DirectoryScanner scanner = new DirectoryScanner();
+        scanner.setBasedir(targetRepoDirectory);
+        StringTokenizer tokenizer = new StringTokenizer(patterns.toString(),", \r\n\t",false);
+        String[] incls = new String[tokenizer.countTokens()];
+        int i = 0;
+        while (tokenizer.hasMoreTokens())
+        {
+            String tok = tokenizer.nextToken();
+            incls[i] = tok;
+            i++;
+        }
+        scanner.setIncludes(incls);
+        scanner.scan();
+        String[] includedFiles = scanner.getIncludedFiles();
+        StringBuilder excluded = null;
+        for (String incl : includedFiles)
+        {
+            incl = incl.replace('\\','/');
+            if (excluded == null)
+            {
+                excluded = new StringBuilder(incl);
+            }
+            else
+            {
+                excluded.append("," + incl);
+            }
+        }
+        return excluded.toString();
+    }
+
+
+    private String[] generatePackExecuteString(String jarPackerLoc, String toPack, String outputDirectory)
+    {
+
+        // http://wiki.eclipse.org/index.php/Pack200
+        /*
+         * 3.5 style: java -cp org.eclipse.equinox.p2.jarprocessor_1.0.100.v20090520-1905.jar org.eclipse.equinox.internal.p2.jarprocessor.Main -processAll
+         * -repack -sign signing-script.sh -outputDir ./out eclipse-SDK.zip 3.6 syle: java -jar org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100123-1019.jar
+         * -processAll -repack -sign signing-script.sh -pack -outputDir ./out eclipse-SDK.zip
+         */
+        return new String[]
+        { "-Dorg.eclipse.update.jarprocessor.pack200=" + pack200, "-jar", jarPackerLoc, "-processAll", "-pack", "-repack",
+                // this does not work with the new version of the jar processor
+                /*
+                 * "-f", FileUtils.dirname(jarPackerLoc) + File.separator + "pack.properties",
+                 */
+                "-verbose", "-outputDir", outputDirectory, toPack };
+
+    }
+
+    private void positionPackJarForExecution() throws MojoExecutionException
+    {
+        info("getting jar packer into position");
+
+        URL jarPacker = this.getClass().getClassLoader().getResource(__PACK_JAR);
+        URL jarProperties = this.getClass().getClassLoader().getResource(__PACK_PROPERTIES);
+        try
+        {
+            FileUtils.copyURLToFile(jarPacker,new File(stagingDirectory + File.separator + __PACK_JAR));
+            FileUtils.copyURLToFile(jarProperties,new File(stagingDirectory + File.separator + __PACK_PROPERTIES));
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+            throw new MojoExecutionException("unable to position jar packer",e);
+        }
+    }
+
+    private void packLocally() throws Exception
+    {
+
+        if (!FileUtils.fileExists(packedOutputDirectory))
+        {
+            info("creating directory to hold packed output");
+            FileUtils.mkdir(packedOutputDirectory);
+        }
+
+        try
+        {
+            String packTempDirectory = stagingDirectory + File.separator + UUID.randomUUID().toString();
+
+            FileUtils.mkdir(packTempDirectory);
+
+            FileUtils.copyFileToDirectory(inputFile,packTempDirectory);
+
+            CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer();
+            CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
+
+            positionPackJarForExecution();
+
+            Commandline pack = new Commandline();
+            pack.setWorkingDirectory(FileUtils.dirname(packTempDirectory));
+            pack.setExecutable(javaExecutable);
+            pack.addArguments(generatePackExecuteString(stagingDirectory + "/" + __PACK_JAR,inputFile,packedOutputDirectory));
+
+            info("executing pack200, output at end of execution : " + pack);
+            CommandLineUtils.executeCommandLine(pack,out,err);
+
+            String packErrput = IOUtil.toString(new StringReader(err.getOutput()));
+            String packOutput = IOUtil.toString(new StringReader(out.getOutput()));
+
+            info("pack200 output:\n" + packOutput);
+            if (packErrput != null || !"".equals(packErrput))
+            {
+                getLog().error(packErrput);
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            getLog().error(e);
+        }
+    }
+
+    private void info(String log)
+    {
+        getLog().info("[PACK] " + log);
+    }
+
+}
diff --git a/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/SignMojo.java b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/SignMojo.java
new file mode 100644
index 0000000..12f0f9b
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/SignMojo.java
@@ -0,0 +1,374 @@
+package org.eclipse.dash.m4e.eclipse.signing;
+
+//========================================================================
+//Copyright (c) 2010 Intalio, Inc.
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//The Eclipse Public License is available at 
+//http://www.eclipse.org/legal/epl-v10.html
+//The Apache License v2.0 is available at
+//http://www.opensource.org/licenses/apache2.0.php
+//You may elect to redistribute this code under either of these licenses. 
+//========================================================================
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.wagon.CommandExecutor;
+import org.apache.maven.wagon.Streams;
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.archiver.util.DefaultFileSet;
+import org.codehaus.plexus.archiver.zip.ZipArchiver;
+import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
+import org.codehaus.plexus.components.io.fileselectors.FileInfo;
+import org.codehaus.plexus.components.io.fileselectors.FileSelector;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * 
+ * @goal sign
+ * @phase package
+ * @description runs the eclipse signing process
+ */
+public class SignMojo extends AbstractEclipseSigningMojo
+{
+
+    /**
+     * Accepted values are 'local' and 'remote'
+     * 
+     * @parameter default-value="local"
+     * @required
+     */
+    protected String execute;
+
+    /**
+     * zip file to get signed
+     * 
+     * @parameter default-value= "${project.build.directory}/packed/site_assembly.zip"
+     * @required
+     */
+    protected String inputFile;
+
+    /**
+     * zip file to get signed
+     * 
+     * @parameter default-value= "${project.build.directory}/signed/site_assembly.zip"
+     * @required
+     */
+    protected String outputFile;
+
+    /**
+     * directory to send artifact to be signed
+     * 
+     * should be akin to: /home/data/httpd/download-staging.priv/rt/<project>
+     * 
+     * @parameter
+     * @required
+     */
+    protected String signerInputDirectory;
+
+    /**
+     * directory monitor for signed artifact
+     * 
+     * @parameter
+     */
+    protected String signerOutputDirectory;
+
+    /**
+     * directory monitor interval for signed artifact
+     * 
+     * @parameter default-value="60000"
+     * @required
+     */
+    protected int zipCheckInterval;
+
+    /**
+     * directory monitor for signed artifact
+     * 
+     * @parameter default-value="30"
+     * @required
+     */
+    protected int maxZipChecks;
+
+    /** @component */
+    protected PlexusContainer plexus;
+
+    public void execute() throws MojoExecutionException, MojoFailureException
+    {
+
+        if (!FileUtils.fileExists(inputFile))
+            throw new MojoExecutionException("zip file does not exist - " + inputFile);
+
+        try
+        {
+
+            if (!FileUtils.fileExists(FileUtils.dirname(outputFile)))
+            {
+                info("creating directory to hold signed artifact");
+                FileUtils.mkdir(FileUtils.dirname(outputFile));
+            }
+
+            System.err.println("input file " + inputFile);
+
+            // remove the *.pack.gz if any:
+            File in = new File(inputFile);
+            ZipUnArchiver unarchive = (ZipUnArchiver)plexus.lookup(ZipUnArchiver.ROLE,"zip");
+            File dest = new File(in.getParentFile(),"repository");
+            dest.mkdir();
+            unarchive.setDestDirectory(dest);
+            unarchive.setSourceFile(in);
+            unarchive.setFileSelectors(new FileSelector[]
+            { new FileSelector()
+            {
+                public boolean isSelected(FileInfo arg0) throws IOException
+                {
+                    return !arg0.getName().endsWith(".pack.gz");
+                }
+
+            } });
+            System.err.println(unarchive.getSourceFile() + " - unarchived into - " + unarchive.getDestDirectory());
+            System.err.println(unarchive.getSourceFile().getAbsolutePath() + " unarchived into " + unarchive.getDestDirectory().getAbsolutePath());
+            unarchive.extract();// path, new File(in.getParentFile(), "repository"));
+
+            FileUtils.rename(in,new File(in.getParentFile(),in.getName() + "-before-removing-pack-gz.zip"));
+
+            ZipArchiver archiver = (ZipArchiver)plexus.lookup(ZipArchiver.ROLE,"zip");// new ZipArchiver();
+            // archiver.addDirectory(unarchive.getDestDirectory(), "repository");//, new String[] {"**/*.jar"}, new String[] {"**/*.pack.gz"});
+            DefaultFileSet fileset = new DefaultFileSet();
+            fileset.setDirectory(unarchive.getDestDirectory());
+            fileset.setFileSelectors(new FileSelector[]
+            { new FileSelector()
+            {
+                public boolean isSelected(FileInfo arg0) throws IOException
+                {
+                    System.err.println("looking at " + arg0.getName());
+                    return !arg0.getName().endsWith(".pack.gz");
+                }
+
+            } });
+            archiver.addFileSet(fileset);
+            File tmpDest = new File(in.getParentFile(),in.getName() + "-after-removing.zip");
+            archiver.setDestFile(tmpDest);
+            System.err.println("....archive " + unarchive.getDestDirectory() + " into " + new File(inputFile).getAbsolutePath());
+            archiver.createArchive();
+            FileUtils.copyFile(tmpDest,in);
+
+            if ("local".equals(execute))
+            {
+                signLocally();
+            }
+            else if ("remote".equals(execute))
+            {
+                signRemotely();
+            }
+
+        }
+        catch (Exception e)
+        {
+        	getLog().error(e);
+        	if (e instanceof MojoExecutionException)
+        	{
+        		throw (MojoExecutionException)e;
+        	}
+        	if (e instanceof MojoFailureException)
+        	{
+        		throw (MojoFailureException)e;
+        	}
+        }
+    }
+
+    private void signLocally() throws Exception
+    {
+        signerInputDirectory = signerInputDirectory + File.separator + UUID.randomUUID().toString();
+
+        signerOutputDirectory = signerInputDirectory + File.separator + "signed";
+
+        FileUtils.mkdir(signerInputDirectory);
+        
+        if (!FileUtils.fileExists(signerInputDirectory))
+        {
+            throw new MojoFailureException("Unable to create the directory " + signerInputDirectory);
+        }
+
+        FileUtils.mkdir(signerOutputDirectory);
+        FileUtils.copyFile(new File(inputFile),new File(signerInputDirectory + File.separator + FileUtils.filename(inputFile)));
+
+        Process pc = Runtime.getRuntime().exec(new String[]
+        { "/bin/chmod", "-R", "ugo+rw", signerInputDirectory });
+        pc.waitFor();
+
+        Process ps = Runtime.getRuntime().exec(new String[]
+        { "/usr/bin/sign", signerInputDirectory + File.separator + FileUtils.filename(inputFile), "nomail", signerOutputDirectory });
+
+        BufferedReader is = new BufferedReader(new InputStreamReader(ps.getInputStream()));
+
+        String liner;
+        while ((liner = is.readLine()) != null)
+            System.out.println(liner);
+
+        System.out.println("In Main after EOF");
+        System.out.flush();
+        try
+        {
+            ps.waitFor(); // wait for process to complete
+        }
+        catch (InterruptedException e)
+        {
+            System.err.println(e); // "Can'tHappen"
+            return;
+        }
+
+        boolean keepChecking = true;
+        int count = 0;
+        while (keepChecking && count < maxZipChecks)
+        {
+            try
+            {
+                info("monitoring for signed file in " + signerOutputDirectory);
+                ++count;
+                Thread.sleep(zipCheckInterval);
+
+                
+                @SuppressWarnings("unchecked")
+                List<String> signedDirList = FileUtils.getFileNames(new File(signerOutputDirectory),"**",null,true);
+
+                info("signed dir output: " + signedDirList.size());
+
+                for (String line : signedDirList)
+                {
+                    getLog().info("-> " + line);
+                }
+
+                if (signedDirList.size() == 1) // . .. signed file
+                {
+                    // if ( FileUtils.filename(toSignZipFile).equals(signedDirList.get(0)))
+                    // {
+                    info("found the signed file");
+                    keepChecking = false;
+                    // }
+                }
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+
+        if (count == maxZipChecks)
+        {
+            getLog().error("signer process never signaled completion");
+            FileUtils.deleteDirectory(signerInputDirectory);
+            return;
+        }
+        else
+        {
+            getLog().info("copying signed artifact to :" + outputFile);
+            FileUtils.copyFile(new File(signerOutputDirectory + File.separator + FileUtils.filename(inputFile)),new File(outputFile));
+            FileUtils.deleteDirectory(signerInputDirectory);
+            return;
+        }
+
+    }
+
+    private void signRemotely() throws Exception
+    {
+        Wagon wagon = createWagon(serverId,getWagonUrl());
+
+        CommandExecutor exec = getCommandExecutor(wagon);
+
+        signerInputDirectory = UUID.randomUUID().toString();
+
+        signerOutputDirectory = signerInputDirectory + File.separator + "signed";
+
+        info("creating remote input directory");
+        exec.executeCommand("/bin/mkdir -p " + signerInputDirectory);
+
+        info("setting permissions");
+        exec.executeCommand("/bin/mkdir -p " + signerOutputDirectory);
+
+        info("copying file to sign to remote directory");
+        wagon.put(new File(inputFile),signerInputDirectory + File.separator + FileUtils.filename(inputFile));
+
+        info("setting permissions on file");
+        exec.executeCommand("/bin/chmod -R ugo+rw " + signerInputDirectory);
+
+        info("calling sign script");
+        info("/usr/bin/sign " + adjustToWagonPath(signerInputDirectory) + File.separator + FileUtils.filename(inputFile) + " nomail signed");
+
+        Streams s = exec.executeCommand("/usr/bin/sign " + adjustToWagonPath(signerInputDirectory) + File.separator + FileUtils.filename(inputFile)
+                + " nomail signed",false);
+
+        info("sign script output\n" + s.getOut());
+
+        boolean keepChecking = true;
+        int count = 0;
+        while (keepChecking && count < maxZipChecks)
+        {
+            try
+            {
+                info("monitoring for signed file");
+                ++count;
+                Thread.sleep(zipCheckInterval);
+
+                @SuppressWarnings("unchecked")
+                List<String> signedDirList = exec.getFileList(signerOutputDirectory);
+
+                info("signed dir output:");
+
+                for (String line : signedDirList)
+                {
+                    getLog().info("-> " + line);
+                }
+
+                if (signedDirList.size() == 1) // . .. signed file
+                {
+                    // if ( FileUtils.filename(toSignZipFile).equals(signedDirList.get(0)))
+                    // {
+                    info("found the signed file");
+                    keepChecking = false;
+                    // }
+                }
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+
+        if (count == maxZipChecks)
+        {
+            getLog().error("signer process never signaled completion");
+            cleanup(exec,signerInputDirectory);
+            return;
+        }
+        else
+        {
+            getLog().info("copying signed artifact to :" + outputFile);
+            wagon.get(signerOutputDirectory + File.separator + FileUtils.filename(inputFile),new File(outputFile));
+            cleanup(exec,signerInputDirectory);
+            return;
+        }
+
+    }
+
+    private void cleanup(CommandExecutor exec, String signerInputDirectory) throws Exception
+    {
+        exec.executeCommand("/bin/rm -Rf " + adjustToWagonPath(signerInputDirectory));
+        // FileUtils.removePath(signerInputDirectory);
+        // FileUtils.removePath(signerOutputDirectory);
+    }
+
+    private void info(String log)
+    {
+        getLog().info("[SIGN] " + log);
+    }
+}
diff --git a/eclipse-signing-maven-plugin/src/main/resources/org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100503a.jar b/eclipse-signing-maven-plugin/src/main/resources/org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100503a.jar
new file mode 100644
index 0000000..5149366
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/resources/org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100503a.jar
Binary files differ
diff --git a/eclipse-signing-maven-plugin/src/main/resources/pack.properties b/eclipse-signing-maven-plugin/src/main/resources/pack.properties
new file mode 100644
index 0000000..b212c86
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/resources/pack.properties
@@ -0,0 +1,2 @@
+pack200.default.args=-E4
+pack.excludes=eclipse/plugins/@excludejars@
\ No newline at end of file