diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/GeneratorException.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/GeneratorException.java
new file mode 100644
index 0000000..10c6473
--- /dev/null
+++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/GeneratorException.java
@@ -0,0 +1,32 @@
+package org.apache.maven.tools.plugin.generator;
+/*
+ * 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.
+ */
+
+/**
+ * @author Olivier Lamy
+ * @since 3.0
+ */
+public class GeneratorException
+ extends Exception
+{
+ public GeneratorException( String s, Throwable throwable )
+ {
+ super( s, throwable );
+ }
+}
diff --git a/maven-plugin-tools-api/src/main/resources/help-class-source.vm b/maven-plugin-tools-api/src/main/resources/help-class-source.vm
new file mode 100644
index 0000000..faf7beb
--- /dev/null
+++ b/maven-plugin-tools-api/src/main/resources/help-class-source.vm
@@ -0,0 +1,311 @@
+#if ($helpPackageName.length>0)
+ package ${helpPackageName};
+#end
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+
+/**
+ * @author
+ * @version
+ */
+@Mojo( name = "help", threadSafe = true, requiresProject = false)
+public class HelpMojo
+ extends AbstractMojo
+{
+ /**
+ * If true, display all settable properties for each goal.
+ *
+ */
+ @Parameter( expression = "${detail}", defaultValue = "false" )
+ private boolean detail;
+
+ /**
+ * The name of the goal for which to show help. If unspecified, all goals will be displayed.
+ *
+ */
+ @Parameter( expression = "${goal}" )
+ private java.lang.String goal;
+
+ /**
+ * The maximum length of a display line, should be positive.
+ *
+ */
+ @Parameter( expression = "${lineLength}", defaultValue = "80" )
+ private int lineLength;
+
+ /**
+ * The number of spaces per indentation level, should be positive.
+ *
+ */
+ @Parameter( expression = "${indentSize}", defaultValue = "2" )
+ private int indentSize;
+
+ // groupId/artifactId/version
+ private String pluginDescriptorPath = "${propertiesFilePath}";
+
+ private Xpp3Dom build()
+ throws MojoExecutionException
+ {
+ // olamy more than one pluginDescriptor in the classloader possible ?
+ InputStream is = getClass().getResourceAsStream( pluginDescriptorPath );
+ try
+ {
+ return Xpp3DomBuilder.build( is, "ISO-8859-1" );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new MojoExecutionException( e.getMessage(), e );
+ }
+ catch ( IOException e )
+ {
+ throw new MojoExecutionException( e.getMessage(), e );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void execute()
+ throws MojoExecutionException
+ {
+ if ( lineLength <= 0 )
+ {
+ getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." );
+ lineLength = 80;
+ }
+ if ( indentSize <= 0 )
+ {
+ getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." );
+ indentSize = 2;
+ }
+
+ // FIXME encoding as parameter
+ Xpp3Dom pluginElement = build();
+
+ StringBuffer sb = new StringBuffer();
+ /**
+ *
Repeat a String n times to form a new string.
repeat < 0
+ * @throws NullPointerException if str is null
+ */
+ private static String repeat( String str, int repeat )
+ {
+ StringBuffer buffer = new StringBuffer( repeat * str.length() );
+
+ for ( int i = 0; i < repeat; i++ )
+ {
+ buffer.append( str );
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * Append a description to the buffer by respecting the indentSize and lineLength parameters.
+ * Note: The last character is always a new line.
+ *
+ * @param sb The buffer to append the description, not null.
+ * @param description The description, not null.
+ * @param indent The base indentation level of each line, must not be negative.
+ */
+ private void append( StringBuffer sb, String description, int indent )
+ {
+ for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
+ {
+ sb.append( it.next().toString() ).append( '\n' );
+ }
+ }
+
+ /**
+ * Splits the specified text into lines of convenient display length.
+ *
+ * @param text The text to split into lines, must not be null.
+ * @param indent The base indentation level of each line, must not be negative.
+ * @param indentSize The size of each indentation, must not be negative.
+ * @param lineLength The length of the line, must not be negative.
+ * @return The sequence of display lines, never null.
+ * @throws NegativeArraySizeException if indent < 0
+ */
+ private static List toLines( String text, int indent, int indentSize, int lineLength )
+ {
+ Listnull.
+ * @param line The line to add, must not be null.
+ * @param indentSize The size of each indentation, must not be negative.
+ * @param lineLength The length of the line, must not be negative.
+ */
+ private static void toLines( Listnull.
+ * @return The indentation level of the line.
+ */
+ private static int getIndentLevel( String line )
+ {
+ int level = 0;
+ for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
+ {
+ level++;
+ }
+ for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
+ {
+ if ( line.charAt( i ) == '\t' )
+ {
+ level++;
+ break;
+ }
+ }
+ return level;
+ }
+
+
+}