diff --git a/hibernate-maven-plugin/pom.xml b/hibernate-maven-plugin/pom.xml
new file mode 100644
index 0000000000..6236b2690a
--- /dev/null
+++ b/hibernate-maven-plugin/pom.xml
@@ -0,0 +1,60 @@
+
+
+
+
+ 4.0.0
+
+
+ hibernate-parent
+ org.hibernate
+ 3.5.0-SNAPSHOT
+ ../parent/pom.xml
+
+
+ org.hibernate
+ hibernate-maven-plugin
+ maven-plugin
+
+ Hibernate Maven Plugin
+ Maven plugin for various Hibernate-tools
+
+
+
+ ${groupId}
+ hibernate-core
+ ${version}
+
+
+ org.apache.maven
+ maven-plugin-api
+ 2.0.9
+
+
+ org.apache.maven
+ maven-project
+ 2.0.9
+
+
+
+
diff --git a/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java b/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java
new file mode 100644
index 0000000000..8a883e7abb
--- /dev/null
+++ b/hibernate-maven-plugin/src/main/java/org/hibernate/maven/InstrumentationMojo.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.maven;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+import java.io.File;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.DirectoryScanner;
+
+import org.hibernate.bytecode.buildtime.Instrumenter;
+import org.hibernate.bytecode.buildtime.Logger;
+import org.hibernate.bytecode.buildtime.JavassistInstrumenter;
+import org.hibernate.bytecode.buildtime.CGLIBInstrumenter;
+
+/**
+ * @goal instrument
+ * @phase process-classes
+ * @requiresDependencyResolution
+ *
+ * @author Steve Ebersole
+ */
+public class InstrumentationMojo extends AbstractMojo implements Instrumenter.Options {
+ /**
+ * INTERNAL : The Maven Project to which we are attached
+ *
+ * @parameter expression="${project}"
+ * @required
+ */
+ private MavenProject project;
+
+ /**
+ * Specifies the directory containing the classes to be instrumented. By default we use the
+ * project's output directory, which in turn defaults to ${basedir}/target/classes.
+ *
+ * @parameter expression="${project.build.outputDirectory}"
+ * @required
+ */
+ private File instrumentationDirectory;
+
+ /**
+ * @parameter
+ */
+ private boolean extended;
+
+ /**
+ * @parameter
+ */
+ private String provider;
+
+ public boolean performExtendedInstrumentation() {
+ return extended;
+ }
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ // first, lets determine whether to apply cglib or javassist based instrumentation...
+ if ( provider == null ) {
+ provider = determineProvider();
+ if ( provider == null ) {
+ throw new MojoExecutionException( "Unable to determine provider to use" );
+ }
+ }
+
+ Instrumenter instrumenter = resolveInstrumenter( provider, new LoggingBridge() );
+ try {
+ instrumenter.execute( collectFilesToProcess() );
+ }
+ catch ( Throwable t ) {
+ throw new MojoExecutionException( "Error executing instrumentation", t );
+ }
+ }
+
+ private Set collectFilesToProcess() {
+ DirectoryScanner scanner = new DirectoryScanner();
+ scanner.setBasedir( instrumentationDirectory );
+ scanner.setIncludes( new String[] { "**/*.class" } );
+ scanner.addDefaultExcludes();
+ scanner.scan();
+ String[] includedFiles = scanner.getIncludedFiles();
+ HashSet fileSet = new HashSet( includedFiles.length + (int)(.75*includedFiles.length) + 1 );
+ fileSet.addAll( Arrays.asList( includedFiles ) );
+ return fileSet;
+ }
+
+ private Instrumenter resolveInstrumenter(String provider, Logger logger) throws MojoExecutionException {
+ if ( "javassist".equals( provider ) ) {
+ return new JavassistInstrumenter( logger, this );
+ }
+ else if ( "cglib".equals( provider ) ) {
+ return new CGLIBInstrumenter( logger, this );
+ }
+ else {
+ throw new MojoExecutionException( "Unable to resolve provider [" + provider + "] to appropriate instrumenter" );
+ }
+ }
+
+ /**
+ * Determine the provider to use. Called in the cases where the user did not explicitly specify; so we look
+ * through the dependencies for the project and decide which provider should be applied.
+ *
+ * NOTE: this impl prefers javassist.
+ *
+ * @return The provider determined from project's dependencies.
+ */
+ private String determineProvider() {
+ if ( project.getCompileArtifacts() != null ) {
+ boolean foundCglib = false;
+ Iterator itr = project.getCompileArtifacts().iterator();
+ while ( itr.hasNext() ) {
+ final Artifact artifact = ( Artifact ) itr.next();
+ if ( "javassist".equals( artifact.getGroupId() ) && "javassist".equals( artifact.getArtifactId() ) ) {
+ return "javassist";
+ }
+ else if ( "org.hibernate".equals( artifact.getGroupId() )
+ && "hibernate-cglib-repack".equals( artifact.getArtifactId() ) ) {
+ foundCglib = true;
+ }
+ }
+ if ( foundCglib ) {
+ return "cglib";
+ }
+ }
+ return null;
+ }
+
+ private class LoggingBridge implements Logger {
+ public void trace(String message) {
+ getLog().debug( message );
+ }
+
+ public void debug(String message) {
+ getLog().debug( message );
+ }
+
+ public void info(String message) {
+ getLog().info( message );
+ }
+
+ public void warn(String message) {
+ getLog().warn( message );
+ }
+
+ public void error(String message) {
+ getLog().error( message );
+ }
+ }
+}