diff --git a/.gitignore b/.gitignore
index 0f182a0..ab31b20 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,2 @@
*.class
-# Package Files #
-*.jar
-*.war
-*.ear
diff --git a/merge-jar-services/.classpath b/merge-jar-services/.classpath
new file mode 100644
index 0000000..271faf6
--- /dev/null
+++ b/merge-jar-services/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/merge-jar-services/.gitignore b/merge-jar-services/.gitignore
new file mode 100644
index 0000000..f5fc778
--- /dev/null
+++ b/merge-jar-services/.gitignore
@@ -0,0 +1,3 @@
+bin
+build
+
diff --git a/merge-jar-services/.project b/merge-jar-services/.project
new file mode 100644
index 0000000..f2c3163
--- /dev/null
+++ b/merge-jar-services/.project
@@ -0,0 +1,17 @@
+
+
+ merge-jar-services
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/merge-jar-services/.settings/org.eclipse.jdt.core.prefs b/merge-jar-services/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..54e493c
--- /dev/null
+++ b/merge-jar-services/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+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
diff --git a/merge-jar-services/lib/ant-1.7.0-jar.jar b/merge-jar-services/lib/ant-1.7.0-jar.jar
new file mode 100644
index 0000000..0a56a58
Binary files /dev/null and b/merge-jar-services/lib/ant-1.7.0-jar.jar differ
diff --git a/merge-jar-services/lib/ant-1.7.0-source.jar b/merge-jar-services/lib/ant-1.7.0-source.jar
new file mode 100644
index 0000000..4cf8ef4
Binary files /dev/null and b/merge-jar-services/lib/ant-1.7.0-source.jar differ
diff --git a/merge-jar-services/lib/ant-launcher-1.7.0-jar.jar b/merge-jar-services/lib/ant-launcher-1.7.0-jar.jar
new file mode 100644
index 0000000..12a1e78
Binary files /dev/null and b/merge-jar-services/lib/ant-launcher-1.7.0-jar.jar differ
diff --git a/merge-jar-services/src/org/pescuma/mergeservices/MergeServicesTask.java b/merge-jar-services/src/org/pescuma/mergeservices/MergeServicesTask.java
new file mode 100644
index 0000000..738077a
--- /dev/null
+++ b/merge-jar-services/src/org/pescuma/mergeservices/MergeServicesTask.java
@@ -0,0 +1,103 @@
+package org.pescuma.mergeservices;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.FileResourceIterator;
+
+public class MergeServicesTask extends Task {
+
+ private File dest;
+ private final List filesets = new ArrayList();
+
+ public void setDest(File dest) {
+ this.dest = dest;
+ }
+
+ public void addFileset(FileSet set) {
+ filesets.add(set);
+ }
+
+ @Override
+ public void execute() throws BuildException {
+ for (FileSet fileSet : filesets) {
+ process(fileSet);
+ }
+ }
+
+ private void process(FileSet fileSet) {
+ DirectoryScanner ds = fileSet.getDirectoryScanner();
+ Iterator> iter = new FileResourceIterator(fileSet.getDir(), ds.getIncludedFiles());
+
+ while (iter.hasNext()) {
+ FileResource resource = (FileResource) iter.next();
+ process(resource.getFile());
+ }
+
+ }
+
+ private void process(File file) {
+ try {
+
+ ZipFile zip = new ZipFile(file);
+ for (Enumeration extends ZipEntry> e = zip.entries(); e.hasMoreElements();) {
+ ZipEntry entry = e.nextElement();
+ if (!entry.isDirectory() && entry.getName().startsWith("META-INF/services/"))
+ process(zip, entry);
+ }
+
+ } catch (IOException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ private void process(ZipFile zip, ZipEntry entry) throws IOException {
+ File result = new File(dest, entry.getName());
+
+ if (!result.getParentFile().exists() && !result.getParentFile().mkdirs())
+ throw new BuildException("Could not create dir " + result.getParent());
+
+ InputStream in = null;
+ OutputStream out = null;
+ try {
+
+ in = zip.getInputStream(entry);
+ out = new FileOutputStream(result, true);
+
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0)
+ out.write(buf, 0, len);
+
+ } finally {
+ close(out);
+ close(in);
+ }
+ }
+
+ private void close(Closeable writer) {
+ try {
+
+ if (writer != null)
+ writer.close();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/merge-jar-services/src/org/pescuma/mergeservices/antlib.xml b/merge-jar-services/src/org/pescuma/mergeservices/antlib.xml
new file mode 100644
index 0000000..e8064cf
--- /dev/null
+++ b/merge-jar-services/src/org/pescuma/mergeservices/antlib.xml
@@ -0,0 +1,4 @@
+
+
+
+