New Upstream Release - libhibernate-commons-annotations-java

Ready changes

Summary

Merged new upstream version: 6.0.1 (was: 3.2.0.Final).

Resulting package

Built on 2022-05-05T18:24 (took 3m9s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases libhibernate-commons-annotations-java

Lintian Result

Diff

diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..28fc34c
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,5 @@
+Please delete this text, and add a link to the Jira issue solved by this PR;
+see https://hibernate.atlassian.net/browse/HCANN.
+
+Remember to prepend the title of this PR, as well as all commit messages,
+with the key of the Jira issue (`HCANN-<digits>`).
diff --git a/.github/hibernate-github-bot.yml b/.github/hibernate-github-bot.yml
new file mode 100644
index 0000000..edebdfd
--- /dev/null
+++ b/.github/hibernate-github-bot.yml
@@ -0,0 +1,3 @@
+---
+jira:
+  projectKey: "HCANN"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a54324f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,33 @@
+# Typically *NIX text editors, by default, append '~' to files on saving to make backups
+*~
+
+# Gradle work directory
+.gradle
+
+# Build output directies
+/target
+*/target
+/build
+*/build
+
+# IntelliJ specific files/directories
+out
+.idea
+*.ipr
+*.iws
+*.iml
+atlassian-ide-plugin.xml
+
+# Eclipse specific files/directories
+.classpath
+.project
+.settings
+.metadata
+bin
+
+# NetBeans specific files/directories
+.nbattrs
+
+# Miscellaneous
+*.log
+.clover
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..3de5a91
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,55 @@
+buildscript {
+    repositories {
+        mavenCentral()
+        gradlePluginPortal()
+    }
+    dependencies {
+        classpath 'org.hibernate.build.gradle:gradle-maven-publish-auth:2.0.1'
+        classpath 'org.hibernate.build.gradle:gradle-animalSniffer-plugin:1.0.1.Final'
+        classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.5"
+        classpath 'nu.studer:gradle-credentials-plugin:2.1'
+    }
+}
+
+plugins {
+    id 'java-library'
+    id 'maven-publish'
+    id 'nu.studer.credentials' version '2.1'
+    id 'idea'
+    id 'eclipse'
+}
+
+repositories {
+    mavenCentral()
+}
+
+apply from: rootProject.file( 'gradle/base-information.gradle' )
+apply from: rootProject.file( 'gradle/publishing.gradle' )
+
+apply plugin: 'com.diffplug.spotless'
+
+dependencies {
+    testImplementation 'junit:junit:3.8.1'
+}
+
+wrapper {
+    distributionType = Wrapper.DistributionType.ALL
+}
+
+spotless {
+    //Only apply on files added, compared to this git source:
+    ratchetFrom 'origin/main'
+    //Don't fail during the check: rather than enforcing guidelines, we use this plugin to fix mistakes automatically.
+    enforceCheck false
+    java {
+        licenseHeaderFile 'spotless.license.java'
+        removeUnusedImports()
+        importOrder()
+        trimTrailingWhitespace()
+        endWithNewline()
+    }
+}
+tasks.compileJava.dependsOn(spotlessApply)
+
+compileJava.options.encoding = 'UTF-8'
+compileTestJava.options.encoding = 'UTF-8'
diff --git a/changelog.txt b/changelog.txt
index f2be9d8..6b82a76 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,15 +1,54 @@
 Hibernate Annotations Changelog
 ===============================
 
+4.0.1.Final (29-11-2011)
+------------------------
+
+** Task
+    * [HCANN-43] - Move to JBoss Logging 3.1.0.CR2
+
+
+4.0.0.Final (10-11-2011)
+------------------------
+
+* [HCANN-41] - Upgrade JBoss Logging and align version numbers
+* [HCANN-42] - Make sure project build with JDK 7
+
+
+4.0.0.CR2 (31-08-2011)
+----------------------
+
+* [HCANN-40] - Make JBoss logging annotation processor an optional dependency to avoid JDK bug uncovering in Core
+
+
+4.0.0.CR1 (31-08-2011)
+----------------------
+
+** Bug
+    * [HCANN-37] - Upgrade pom.xml info on SCM (move to Git)
+
+** Improvement
+    * [HCANN-36] - Add lgpl.txt file to the repository
+    * [HCANN-39] - Move to new Maven groupId
+
+** New Feature
+    * [HCANN-38] - change to use jboss logging from slf4j
+
+** Task
+    * [HCANN-20] - Update pom to use the new distributationManagement information
+
+
 3.2.0.GA (9-03-2010)
 --------------------
 
 ** New Feature
     * [HCANN-5] - Decouple the reflection work from the metadata overriding facility
 
+
 3.1.0.GA (20-08-2008)
 ----------------------
 
+
 3.1.0.CR2 (23-07-2008)
 ----------------------
 
@@ -25,6 +64,7 @@ Hibernate Annotations Changelog
     * [HCANN-2] - Add POM
     * [HCANN-3] - Make build independent of Hibernate Core structure
 
+
 3.0.0.GA (19-03-2007)
 ---------------------
 
diff --git a/debian/changelog b/debian/changelog
index cf854a2..9e35036 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+libhibernate-commons-annotations-java (6.0.1-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Thu, 05 May 2022 18:21:50 -0000
+
 libhibernate-commons-annotations-java (3.2.0.Final-4) unstable; urgency=medium
 
   * Team upload.
diff --git a/debian/patches/01-java8-compatibility.patch b/debian/patches/01-java8-compatibility.patch
index bca4dff..035ad16 100644
--- a/debian/patches/01-java8-compatibility.patch
+++ b/debian/patches/01-java8-compatibility.patch
@@ -2,9 +2,11 @@ Description: Fixes a test failure with Java 8
 Author: Emmanuel Bourg <ebourg@apache.org>
 Bug: https://hibernate.atlassian.net/browse/HCANN-66
 Bug-Debian: https://bugs.debian.org/750754
---- a/src/test/java/org/hibernate/annotations/common/test/annotationfactory/TestAnnotation.java
-+++ b/src/test/java/org/hibernate/annotations/common/test/annotationfactory/TestAnnotation.java
-@@ -7,7 +7,7 @@
+Index: libhibernate-commons-annotations-java/src/test/java/org/hibernate/annotations/common/test/annotationfactory/TestAnnotation.java
+===================================================================
+--- libhibernate-commons-annotations-java.orig/src/test/java/org/hibernate/annotations/common/test/annotationfactory/TestAnnotation.java
++++ libhibernate-commons-annotations-java/src/test/java/org/hibernate/annotations/common/test/annotationfactory/TestAnnotation.java
+@@ -14,7 +14,7 @@ package org.hibernate.annotations.common
   * @author Paolo Perrotta
   * @author Davide Marchignoli
   */
diff --git a/gradle/base-information.gradle b/gradle/base-information.gradle
new file mode 100644
index 0000000..69eb289
--- /dev/null
+++ b/gradle/base-information.gradle
@@ -0,0 +1,73 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+
+apply plugin: 'base'
+
+File versionFile = file( "${rootProject.projectDir}/gradle/version.properties" )
+
+ext {
+	hcannVersionFile = versionFile
+	hcannVersion = HibernateVersion.fromFile( versionFile, project )
+	// Override during releases
+	if ( project.hasProperty( 'releaseVersion' ) ) {
+		hcannVersion = new HibernateVersion( project.releaseVersion, project )
+	}
+}
+
+group = 'org.hibernate.common'
+version = project.hcannVersion.fullName
+
+buildDir = "target"
+
+java {
+	toolchain {
+		languageVersion.set(JavaLanguageVersion.of(11))
+	}
+}
+
+class HibernateVersion {
+	final String fullName
+	final String majorVersion
+	final String family
+
+	final String osgiVersion
+
+	final boolean isSnapshot
+
+	HibernateVersion(String fullName, Project project) {
+		this.fullName = fullName
+
+		final String[] hibernateVersionComponents = fullName.split( '\\.' )
+		this.majorVersion = hibernateVersionComponents[0]
+		this.family = hibernateVersionComponents[0] + '.' + hibernateVersionComponents[1]
+
+		this.isSnapshot = fullName.endsWith( '-SNAPSHOT' )
+
+		this.osgiVersion = isSnapshot ? family + '.' + hibernateVersionComponents[2] + '.SNAPSHOT' : fullName
+	}
+
+	static HibernateVersion fromFile(File file, Project project){
+		def fullName = readVersionProperties(file)
+		return new HibernateVersion(fullName, project)
+	}
+
+	private static String readVersionProperties(File file) {
+		if ( !file.exists() ) {
+			throw new GradleException( "Version file $file.canonicalPath does not exists" )
+		}
+		Properties versionProperties = new Properties()
+		file.withInputStream {
+			stream -> versionProperties.load( stream )
+		}
+		return versionProperties.hibernateVersion
+	}
+
+	@Override
+	String toString() {
+		return this.fullName
+	}
+}
diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle
new file mode 100644
index 0000000..29b770a
--- /dev/null
+++ b/gradle/publishing.gradle
@@ -0,0 +1,231 @@
+
+apply plugin: 'maven-publish'
+apply plugin: 'nu.studer.credentials'
+
+ext {
+    if ( project.hasProperty( 'hibernatePublishUsername' ) ) {
+        credentials.hibernatePublishUsername = project.property( 'hibernatePublishUsername' )
+    }
+    if ( project.hasProperty( 'hibernatePublishPassword' ) ) {
+        credentials.hibernatePublishPassword = project.property( 'hibernatePublishPassword' )
+    }
+
+    if ( project.hasProperty( 'hibernateSnapshotsUsername' ) ) {
+        credentials.hibernateSnapshotsUsername = project.property( 'hibernateSnapshotsUsername' )
+    }
+    if ( project.hasProperty( 'hibernateSnapshotsPassword' ) ) {
+        credentials.hibernateSnapshotsPassword = project.property( 'hibernateSnapshotsPassword' )
+    }
+
+    gradle.taskGraph.addTaskExecutionGraphListener(
+            new TaskExecutionGraphListener() {
+                @Override
+                void graphPopulated(TaskExecutionGraph graph) {
+                    if ( graph.hasTask( 'publishMavenJavaPublicationToSnapshotRepository' ) ) {
+                        if ( ! project.hcannVersion.isSnapshot ) {
+                            throw new GradleException("Cannot publish non-snapshot version to snapshot repository");
+                        }
+                        if ( project.credentials.hibernateSnapshotsUsername == null ) {
+                            throw new GradleException("Snapshot publishing credentials not specified");
+                        }
+                    }
+
+                    if (graph.hasTask('publishMavenJavaPublicationToOssrhRepository')) {
+                        if ( project.hcannVersion.isSnapshot ) {
+                            throw new GradleException("Cannot publish snapshot version to non-snapshot repository");
+                        }
+                        if (project.credentials.hibernatePublishUsername == null) {
+                            throw new GradleException("Publishing credentials not specified");
+                        }
+                    }
+                }
+            }
+    )
+}
+
+java {
+    withJavadocJar()
+    withSourcesJar()
+}
+
+jar {
+    manifest {
+        attributes(
+                'Main-Class': 'org.hibernate.Version',
+
+                'Implementation-Url': 'http://hibernate.org',
+                'Implementation-Version': archiveVersion,
+                'Implementation-Vendor': 'Hibernate.org',
+                'Implementation-Vendor-Id': 'org.hibernate',
+                'Bundle-Vendor': 'Hibernate.org'
+        )
+//
+//        // See https://discuss.gradle.org/t/balancing-deprecation-of-sourcesetoutput-classesdir-and-other-parts-of-gradle-that-only-accept-a-dir-file/25283
+//        classesDir = sourceSets.main.java.outputDir
+//        classpath = configurations.runtime
+    }
+}
+
+OsgiManifestPackagingInfo.buildInfo( project ).applyTo( jar.manifest )
+
+task sourceJar(type: Jar) {
+    from sourceSets.main.allJava
+}
+
+javadoc {
+    configure( options ) {
+        windowTitle = "$project.name JavaDocs"
+        docTitle = "$project.name JavaDocs ($project.version)"
+        use = true
+        encoding = 'UTF-8'
+        links += ['https://docs.oracle.com/en/java/javase/11/docs/api/']
+        tags = ["apiNote", 'implSpec', 'implNote', 'todo']
+
+        addStringOption('Xdoclint:none', '-quiet')
+    }
+}
+
+publishing {
+    publications {
+        mavenJava(MavenPublication) {
+            from components.java
+
+            pom {
+                name = 'Hibernate Commons Annotations'
+                description = 'Common reflection code used in support of annotation processing'
+                url = 'http://hibernate.org'
+
+                organization {
+                    name = 'Hibernate.org'
+                    url = 'http://hibernate.org'
+                }
+
+                licenses {
+                    license {
+                        name = 'GNU Library General Public License v2.1 or later'
+                        url = 'http://www.opensource.org/licenses/LGPL-2.1'
+                        comments = 'See discussion at http://hibernate.org/community/license/ for more details.'
+                        distribution = 'repo'
+                    }
+                }
+
+                scm {
+                    url = 'http://github.com/hibernate/hibernate-commons-annotations'
+                    connection = 'scm:git:http://github.com/hibernate/hibernate-commons-annotations.git'
+                    developerConnection = 'scm:git:git@github.com:hibernate/hibernate-commons-annotations.git'
+                }
+
+                issueManagement {
+                    system = 'jira'
+                    url = 'https://hibernate.atlassian.net/browse/HCANN'
+                }
+
+                developers {
+                    developer {
+                        id = 'hibernate-team'
+                        name = 'The Hibernate Development Team'
+                        organization = 'Hibernate.org'
+                        organizationUrl = 'http://hibernate.org'
+                    }
+                }
+            }
+        }
+    }
+
+    repositories {
+        maven {
+            if ( project.hcannVersion.isSnapshot ) {
+                name 'snapshots'
+                url 'https://oss.sonatype.org/content/repositories/snapshots/'
+
+                credentials {
+                    username project.credentials.hibernateSnapshotsUsername
+                    password project.credentials.hibernateSnapshotsPassword
+                }
+            }
+            else {
+                name 'ossrh'
+                url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
+
+                credentials {
+                    username project.credentials.hibernatePublishUsername
+                    password project.credentials.hibernatePublishPassword
+                }
+            }
+        }
+    }
+}
+
+// OSGi manifest helpers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class OsgiManifestPackagingInfo {
+    private String[] exportPackageInstructions;
+    private String[] privatePackageInstructions;
+
+    String[] getExportPackageInstructions() {
+        return exportPackageInstructions
+    }
+
+    String[] getPrivatePackageInstructions() {
+        return privatePackageInstructions
+    }
+
+    public static OsgiManifestPackagingInfo buildInfo(Project project) {
+        final String exportPackageVersion = project.version.replaceAll( "-SNAPSHOT", "" )
+                .replaceAll( ".Final-redhat-", "DO_NOT_REPLACE" )
+                .replaceAll( ".Final", "" )
+                .replaceAll( "DO_NOT_REPLACE", ".Final-redhat-" );
+
+        final Set<String> exportPackageInstructionSet = new HashSet<String>()
+        final Set<String> privatePackageInstructionSet = new HashSet<String>()
+
+        final SourceDirectorySet sourceDirectorySet = project.sourceSets.main.java;
+        sourceDirectorySet.each { javaSrcFile ->
+            final String packageName = determinePackageName( sourceDirectorySet, javaSrcFile );
+            if ( packageName.endsWith( ".internal" )
+                    || packageName.contains( ".internal." ) ) {
+                privatePackageInstructionSet.add( packageName );
+            }
+            else {
+                exportPackageInstructionSet.add( packageName + ";version=\"" + exportPackageVersion + "\"" );
+            }
+        }
+
+        return new OsgiManifestPackagingInfo(
+                exportPackageInstructionSet.toArray( new String[ exportPackageInstructionSet.size() ] ),
+                privatePackageInstructionSet.toArray( new String[ privatePackageInstructionSet.size() ] )
+        );
+    }
+
+    private static String determinePackageName(SourceDirectorySet sourceDirectorySet, File javaFile) {
+        if (javaFile.name.equals("module-info.java")) {
+            return "";
+        }
+        final javaFileAbsolutePath = javaFile.absolutePath;
+        for ( File sourceDirectory : sourceDirectorySet.srcDirs ) {
+            final String sourceDirectoryAbsolutePath = sourceDirectory.absolutePath;
+            if ( javaFileAbsolutePath.startsWith( sourceDirectoryAbsolutePath ) ) {
+                final String javaFileRelativePath = javaFileAbsolutePath.substring(
+                        sourceDirectoryAbsolutePath.length() + 1,
+                        javaFileAbsolutePath.lastIndexOf( File.separator )
+                );
+                return javaFileRelativePath.replace( File.separator, "." );
+            }
+        }
+        throw new RuntimeException( "ugh" );
+    }
+
+    private OsgiManifestPackagingInfo(String[] exportPackageInstructions, String[] privatePackageInstructions) {
+        this.exportPackageInstructions = exportPackageInstructions
+        this.privatePackageInstructions = privatePackageInstructions
+    }
+
+    def applyTo(def manifest) {
+        if ( exportPackageInstructions.length > 0 ) {
+            manifest.attributes( 'Export-Package': exportPackageInstructions )
+        }
+        if ( privatePackageInstructions.length > 0 ) {
+            manifest.attribute( 'Private-Package', privatePackageInstructions )
+        }
+    }
+}
diff --git a/gradle/version.properties b/gradle/version.properties
new file mode 100644
index 0000000..0885289
--- /dev/null
+++ b/gradle/version.properties
@@ -0,0 +1 @@
+hibernateVersion=6.0.1.Final
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..7454180
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..ac0b842
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.2-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..1b6c787
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed 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
+#
+#      https://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.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..ac1b06f
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/lgpl.txt b/lgpl.txt
new file mode 100644
index 0000000..4362b49
--- /dev/null
+++ b/lgpl.txt
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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 library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/pom.xml b/pom.xml
deleted file mode 100644
index 4bfa21d..0000000
--- a/pom.xml
+++ /dev/null
@@ -1,163 +0,0 @@
-<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/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-commons-annotations</artifactId>
-    <packaging>jar</packaging>
-    <version>3.2.0.Final</version>
-
-    <name>Hibernate Commons Annotations</name>
-    <description>Common reflection code used in support of annotation processing</description>
-    <url>http://hibernate.org</url>
-    <inceptionYear>2005</inceptionYear>
-
-    <organization>
-        <name>Hibernate.org</name>
-        <url>http://hibernate.org</url>
-    </organization>
-
-    <licenses>
-		<license>
-			<name>GNU LESSER GENERAL PUBLIC LICENSE</name>
-			<url>http://www.gnu.org/licenses/lgpl.txt</url>
-		</license>
-	</licenses>
-
-    <developers>
-        <developer>
-            <id>epbernard</id>
-            <name>Emmanuel Bernard</name>
-            <email>emmanuel@hibernate.org</email>
-            <organization>JBoss, a division of Red Hat</organization>
-            <url>http://in.relation.to/Bloggers/Emmanuel</url>
-        </developer>
-    </developers>
-
-    <mailingLists>
-        <mailingList>
-            <name>Hibernate Announcements</name>
-            <post>hibernate-announce@lists.jboss.org</post>
-            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</subscribe>
-            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</unsubscribe>
-            <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
-        </mailingList>
-        <mailingList>
-            <name>Hibernate Commit Notificatons</name>
-            <post>hibernate-commits@lists.jboss.org</post>
-            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</subscribe>
-            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</unsubscribe>
-            <archive>http://lists.jboss.org/pipermail/hibernate-commits/</archive>
-        </mailingList>
-        <mailingList>
-            <name>Hibernate Developers</name>
-            <post>hibernate-dev@lists.jboss.org</post>
-            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</subscribe>
-            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</unsubscribe>
-            <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
-            <otherArchives>
-                <otherArchive>http://www.mail-archive.com/hibernate-dev%40lists.jboss.org/index.html</otherArchive>
-            </otherArchives>
-        </mailingList>
-        <mailingList>
-            <name>Hibernate Issue Notifications</name>
-            <post>hibernate-issues@lists.jboss.org</post>
-            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</subscribe>
-            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</unsubscribe>
-            <archive>http://lists.jboss.org/pipermail/hibernate-issues/</archive>
-        </mailingList>
-    </mailingLists>
-
-    <issueManagement>
-        <system>jira</system>
-        <url>http://opensource.atlassian.com/projects/hibernate/browse/HCANN</url>
-    </issueManagement>
-
-    <scm>
-        <connection>scm:svn:https://svn.jboss.org/repos/hibernate/commons-annotations/tags/3.2.0.Final</connection>
-        <developerConnection>scm:svn:https://svn.jboss.org/repos/hibernate/commons-annotations/tags/3.2.0.Final</developerConnection>
-        <url>https://svn.jboss.org/repos/hibernate/commons-annotations/tags/3.2.0.Final</url>
-    </scm>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
-        <!-- test-scoped dependencies for common testing dependencies -->
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <version>3.8.1</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>jcl-over-slf4j</artifactId>
-            <version>${slf4jVersion}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <version>${slf4jVersion}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-            <version>99.0-does-not-exist</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging-api</artifactId>
-            <version>99.0-does-not-exist</version>
-            <scope>test</scope>
-        </dependency>
-        <!-- / test-scoped dependencies for common testing dependencies -->
-    </dependencies>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>org.slf4j</groupId>
-                <artifactId>slf4j-api</artifactId>
-                <version>${slf4jVersion}</version>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
-    <distributionManagement>
-        <repository>
-            <!-- Copy the dist to the local checkout of the JBoss maven2 repo ${maven.repository.root} -->
-            <!-- It is anticipated that ${maven.repository.root} be set in user's settings.xml -->
-            <!-- todo : replace this with direct svn access once the svnkit providers are available -->
-            <id>repository.jboss.org</id>
-            <url>file://${maven.repository.root}</url>
-        </repository>
-        <snapshotRepository>
-            <id>snapshots.jboss.org</id>
-            <name>JBoss Snapshot Repository</name>
-            <url>dav:https://snapshots.jboss.org/maven2</url>
-        </snapshotRepository>
-    </distributionManagement>
-
-    <properties>
-        <slf4jVersion>1.5.8</slf4jVersion>
-    </properties>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>1.5</source>
-                    <target>1.5</target>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
\ No newline at end of file
diff --git a/readme.txt b/readme.txt
index 7832c63..36456cc 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,21 +1,36 @@
 Hibernate Commons Annotations
 ==================================================
-Version: @version@, @releasedate@
 
 Description
 -----------
 
-Hibernate Commons Annotations is a utility project used by annotations based
-Hibernate sub-projects.
-It's first scope is to support Java Generics type discovery.
-It's second scope is to support Java Annotations overriding through XML files
-(mainly but not conceptually limited to)
+Hibernate Commons Annotations is a utility project used by several Hibernate projects;
+as a user of Hibernate libraries you probably are not going to use this directly.
 
+Its first scope is to support Java Generics type discovery.
+Its second scope is to support Java Annotations overriding through XML files
+(mainly but not conceptually limited to).
 
-Instructions
+Requirements
 ------------
+Since version 6.0 this project requires Java 11.
 
-TODO: Do something here
+Release Instructions
+------------
+
+Ensure JIRA is up to date and reflecting the state of the branch being released.
+
+Edit the properties file named `gradle/version.properties` to define the version.
+
+Then run the publishing task:
+
+    ./gradlew publish -PhibernatePublishUsername=hibernate_org_ossrh -PhibernatePublishPassword=verySecretPassword
+
+Create a Tag and push it.
+
+Navigate to https://oss.sonatype.org/ to close and release the staged repository.
+
+Reset the `gradle/version.properties` to the next snapshot version for the current branch, push it as well.
 
 
 Contact
@@ -23,17 +38,20 @@ Contact
 
 Latest Documentation:
 
-This project has no documentation per se, because of it's internal use focus.
+This project has no documentation per se, because of its internal use focus.
 Please ask questions to the technical support forum.
 
 Bug Reports:
 
-   Hibernate JIRA (preferred)
-   hibernate-devel@lists.sourceforge.net
+   Hibernate JIRA (preferred): https://hibernate.atlassian.net
+
+Or contact us via chat, mailing list, etc as described on:
+
+   http://hibernate.org/community/
 
-Free Technical Support:
+Free, volunteers based technical support:
 
-   http://forum.hibernate.org (http://forum.hibernate.org/viewforum.php?f=9)
+   https://discourse.hibernate.org
 
 
 Notes
@@ -42,4 +60,4 @@ Notes
 If you want to contribute, go to http://www.hibernate.org/
 
 This software and its documentation are distributed under the terms of the
-FSF Lesser Gnu Public License (see lgpl.txt).
\ No newline at end of file
+GNU Lesser General Public License v2.1 or later (see lgpl.txt).
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..4bb1088
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,11 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
+if ( !JavaVersion.current().isJava11Compatible() ) {
+    throw new GradleException( "Gradle must be run with Java 11" )
+}
+
+rootProject.name = 'hibernate-commons-annotations'
diff --git a/spotless.license.java b/spotless.license.java
new file mode 100644
index 0000000..2602c3b
--- /dev/null
+++ b/spotless.license.java
@@ -0,0 +1,6 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 0000000..e61f82d
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,5 @@
+module org.hibernate.commons.annotations {
+	exports org.hibernate.annotations.common.annotationfactory;
+	exports org.hibernate.annotations.common.reflection;
+	exports org.hibernate.annotations.common.reflection.java;
+}
diff --git a/src/main/java/org/hibernate/annotations/common/AssertionFailure.java b/src/main/java/org/hibernate/annotations/common/AssertionFailure.java
deleted file mode 100644
index 0c07c73..0000000
--- a/src/main/java/org/hibernate/annotations/common/AssertionFailure.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, 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.annotations.common;
-
-import org.slf4j.LoggerFactory;
-import org.slf4j.Logger;
-
-
-/**
- * Indicates failure of an assertion: a possible bug in Hibernate.
- * <p/>
- * TODO : Copy from Hibernate Core, do some mutualization here?
- *
- * @author Gavin King
- * @auhor Emmanuel Bernard
- */
-public class AssertionFailure extends RuntimeException {
-
-	private static final Logger log = LoggerFactory.getLogger(AssertionFailure.class);
-
-	private static final String MESSAGE = "an assertion failure occured (this may indicate a bug in Hibernate)";
-
-	public AssertionFailure(String s) {
-		super(s);
-		log.error(MESSAGE, this);
-	}
-
-	public AssertionFailure(String s, Throwable t) {
-		super(s, t);
-		log.error(MESSAGE, t);
-	}
-
-}
diff --git a/src/main/java/org/hibernate/annotations/common/Version.java b/src/main/java/org/hibernate/annotations/common/Version.java
deleted file mode 100644
index 33ab9db..0000000
--- a/src/main/java/org/hibernate/annotations/common/Version.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, 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.annotations.common;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * @author Emmanuel Bernard
- */
-public class Version {
-	public static final String VERSION = "3.2.0.Final";
-	private static Logger log = LoggerFactory.getLogger( Version.class );
-
-	static {
-		log.info( "Hibernate Commons Annotations {}", VERSION );
-	}
-
-	public static void touch() {
-	}
-}
diff --git a/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationDescriptor.java b/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationDescriptor.java
index 2b4e50a..4ced79a 100644
--- a/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationDescriptor.java
+++ b/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationDescriptor.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.annotationfactory;
 
@@ -38,30 +21,32 @@ import java.util.Map;
  * @author Paolo Perrotta
  * @author Davide Marchignoli
  */
-public class AnnotationDescriptor {
+public final class AnnotationDescriptor {
 
 	private final Class<? extends Annotation> type;
-
-	private final Map<String, Object> elements = new HashMap<String, Object>();
+	private Map<String, Object> elements;
 
 	public AnnotationDescriptor(Class<? extends Annotation> annotationType) {
 		type = annotationType;
 	}
 
 	public void setValue(String elementName, Object value) {
+		if ( elements == null ) {
+			elements = new HashMap<>( 4 ); //likely to be small
+		}
 		elements.put( elementName, value );
 	}
 
 	public Object valueOf(String elementName) {
-		return elements.get( elementName );
+		return elements == null ? null : elements.get( elementName );
 	}
 
 	public boolean containsElement(String elementName) {
-		return elements.containsKey( elementName );
+		return elements == null ? false : elements.containsKey( elementName );
 	}
 
 	public int numberOfElements() {
-		return elements.size();
+		return elements == null ? 0 : elements.size();
 	}
 
 	public Class<? extends Annotation> type() {
diff --git a/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationFactory.java b/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationFactory.java
index 54cb87a..6f9f8e5 100644
--- a/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationFactory.java
+++ b/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationFactory.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.annotationfactory;
 
@@ -36,30 +19,49 @@ import java.lang.reflect.Proxy;
  * @author Davide Marchignoli
  * @see AnnotationProxy
  */
-public class AnnotationFactory {
+public final class AnnotationFactory {
 
-	@SuppressWarnings("unchecked")
+	/**
+	 * Creates an Annotation proxy for the given annotation descriptor.
+	 * <p/>
+	 * NOTE: the proxy here is generated using the ClassLoader of the Annotation type's Class.  E.g.,
+	 * if asked to create an Annotation proxy for javax.persistence.Entity we would use the ClassLoader
+	 * of the javax.persistence.Entity Class for generating the proxy.
+	 *
+	 * @param descriptor The annotation descriptor
+	 *
+	 * @return The annotation proxy
+	 */
 	public static <T extends Annotation> T create(AnnotationDescriptor descriptor) {
-		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-        //TODO round 34ms to generate the proxy, hug! is Javassist Faster?
-        //TODO prebuild the javax.persistence and org.hibernate.annotations classes?
-        Class<T> proxyClass = (Class<T>) Proxy.getProxyClass( classLoader, descriptor.type() );
-		InvocationHandler handler = new AnnotationProxy( descriptor );
-		try {
-			return getProxyInstance( proxyClass, handler );
-		}
-		catch (RuntimeException e) {
-			throw e;
-		}
-		catch (Exception e) {
-			throw new RuntimeException( e );
-		}
+		return create( descriptor, descriptor.type().getClassLoader() );
 	}
 
-	private static <T extends Annotation> T getProxyInstance(Class<T> proxyClass, InvocationHandler handler) throws
-			SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException,
-			IllegalAccessException, InvocationTargetException {
-		Constructor<T> constructor = proxyClass.getConstructor( new Class[]{InvocationHandler.class} );
-		return constructor.newInstance( new Object[]{handler} );
+	/**
+	 * Legacy form of {@link #create(AnnotationDescriptor) using the current Thread#getContextClassLoader
+	 * for proxy generation
+	 *
+	 * @param descriptor The annotation descriptor
+	 *
+	 * @return The annotation proxy
+	 */
+	public static <T extends Annotation> T createUsingTccl(AnnotationDescriptor descriptor) {
+		return create( descriptor, Thread.currentThread().getContextClassLoader() );
+	}
+
+	/**
+	 * Overloaded form of Annotation proxy creation that accepts an explicit ClassLoader.
+	 *
+	 * @param descriptor The annotation descriptor
+	 * @param classLoader The ClassLoader to be used in defining the proxy
+	 *
+	 * @return The annotation proxy
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T extends Annotation> T create(AnnotationDescriptor descriptor, ClassLoader classLoader) {
+		return (T) Proxy.newProxyInstance(
+				classLoader,
+				new Class[] {descriptor.type()},
+				new AnnotationProxy( descriptor )
+		);
 	}
 }
diff --git a/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationProxy.java b/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationProxy.java
index e7c4407..c0bf442 100644
--- a/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationProxy.java
+++ b/src/main/java/org/hibernate/annotations/common/annotationfactory/AnnotationProxy.java
@@ -1,31 +1,15 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.annotationfactory;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Map;
@@ -56,7 +40,7 @@ import java.util.TreeSet;
  * @author Davide Marchignoli
  * @see java.lang.annotation.Annotation
  */
-public class AnnotationProxy implements Annotation, InvocationHandler {
+public final class AnnotationProxy implements Annotation, InvocationHandler {
 
 	private final Class<? extends Annotation> annotationType;
 	//FIXME it's probably better to use String as a key rather than Method
@@ -66,10 +50,12 @@ public class AnnotationProxy implements Annotation, InvocationHandler {
 
 	public AnnotationProxy(AnnotationDescriptor descriptor) {
 		this.annotationType = descriptor.type();
-		values = getAnnotationValues( descriptor );
+		this.values = getAnnotationValues( annotationType, descriptor );
 	}
 
-	private Map<Method, Object> getAnnotationValues(AnnotationDescriptor descriptor) {
+	private static Map<Method, Object> getAnnotationValues(
+			Class<? extends Annotation> annotationType,
+			AnnotationDescriptor descriptor) {
 		Map<Method, Object> result = new HashMap<Method, Object>();
 		int processedValuesFromDescriptor = 0;
 		for ( Method m : annotationType.getDeclaredMethods() ) {
@@ -87,7 +73,19 @@ public class AnnotationProxy implements Annotation, InvocationHandler {
 		if ( processedValuesFromDescriptor != descriptor.numberOfElements() ) {
 			throw new RuntimeException( "Trying to instanciate " + annotationType + " with unknown elements" );
 		}
-		return result;
+		return toSmallMap( result );
+	}
+
+	static <K, V> Map<K, V> toSmallMap(Map<K, V> map) {
+		switch ( map.size() ) {
+			case 0:
+				return Collections.emptyMap();
+			case 1:
+				Map.Entry<K, V> entry = map.entrySet().iterator().next();
+				return Collections.singletonMap( entry.getKey(), entry.getValue() );
+			default:
+				return map;
+		}
 	}
 
 	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
@@ -127,7 +125,6 @@ public class AnnotationProxy implements Annotation, InvocationHandler {
 					}
 				}
 		);
-		//List<Method> result = new LinkedList<Method>();
 		result.addAll( values.keySet() );
 		return result;
 	}
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/AnnotationReader.java b/src/main/java/org/hibernate/annotations/common/reflection/AnnotationReader.java
index f388d8a..83f88b0 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/AnnotationReader.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/AnnotationReader.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection;
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/Filter.java b/src/main/java/org/hibernate/annotations/common/reflection/Filter.java
index f44b5d1..4f3f5a3 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/Filter.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/Filter.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection;
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/MetadataProvider.java b/src/main/java/org/hibernate/annotations/common/reflection/MetadataProvider.java
index e392469..4a0ad91 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/MetadataProvider.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/MetadataProvider.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.reflection;
 
 import java.util.Map;
@@ -7,6 +13,7 @@ import java.lang.reflect.AnnotatedElement;
  * Provides metadata
  *
  * @author Emmanuel Bernard
+ * @author Sanne Grinovero
  */
 public interface MetadataProvider {
 
@@ -16,7 +23,18 @@ public interface MetadataProvider {
 	Map<Object, Object> getDefaults();
 
 	/**
-	 * provide metadata for a gien annotated element
+	 * provide metadata for a given annotated element
 	 */
 	AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement);
+
+	/**
+	 * Reset any internal caches.
+	 * This will free up memory in some implementations, at the cost of
+	 * possibly being a bit slower if its services are needed again.
+	 * Other configuration aspects are not affected.
+	 */
+	default void reset() {
+		//By default a no-op
+	}
+
 }
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/MetadataProviderInjector.java b/src/main/java/org/hibernate/annotations/common/reflection/MetadataProviderInjector.java
index 197ed55..4418ac7 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/MetadataProviderInjector.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/MetadataProviderInjector.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.reflection;
 
 /**
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/ReflectionManager.java b/src/main/java/org/hibernate/annotations/common/reflection/ReflectionManager.java
index eda6f3b..045dbca 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/ReflectionManager.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/ReflectionManager.java
@@ -1,30 +1,14 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection;
 
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Method;
+import java.lang.reflect.Type;
 import java.util.Map;
 
 /**
@@ -32,6 +16,7 @@ import java.util.Map;
  *
  * @author Paolo Perrotta
  * @author Davide Marchignoli
+ * @author Sanne Grinovero
  */
 public interface ReflectionManager {
 
@@ -39,15 +24,39 @@ public interface ReflectionManager {
 
 	public Class toClass(XClass xClazz);
 
-	public Method toMethod(XMethod method);
+	public Type toType(XClass xClazz);
 
-	public <T> XClass classForName(String name, Class<T> caller) throws ClassNotFoundException;
+	public Method toMethod(XMethod method);
 
-	public XPackage packageForName(String packageName) throws ClassNotFoundException;
+	public XPackage toXPackage(Package pkg);
 
 	public <T> boolean equals(XClass class1, Class<T> class2);
 
     public AnnotationReader buildAnnotationReader(AnnotatedElement annotatedElement);
 
     public Map getDefaults();
+
+	/**
+	 * This resets any internal caches.
+	 * This will free up memory in some implementations, at the cost of
+	 * possibly being a bit slower if its services are needed again.
+	 * <p>
+	 *     Ideally the ReflectionManager should be discarded after use,
+	 *     but sometimes that's not posible.
+	 *     This method is intended to be used when there is reasonable
+	 *     expectation for te ReflectionManager to no longer be needed,
+	 *     while having the option to still use it in case the assumption
+	 *     doesn't hold true.
+	 * </p>
+	 * <p>
+	 * Careful: after invoking this method, returned X* instances will
+	 * no longer honour any identity equality contract with X* instances
+	 * which have been returned before resetting the cache.
+	 * </p>
+	 * This operation does not affect the configuration.
+	 */
+	default void reset() {
+		//By default a no-op
+	}
+
 }
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/ReflectionUtil.java b/src/main/java/org/hibernate/annotations/common/reflection/ReflectionUtil.java
index 2e8ba9e..8b86dc1 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/ReflectionUtil.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/ReflectionUtil.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection;
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/XAnnotatedElement.java b/src/main/java/org/hibernate/annotations/common/reflection/XAnnotatedElement.java
index fb5d83f..f4d7534 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/XAnnotatedElement.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/XAnnotatedElement.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection;
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/XClass.java b/src/main/java/org/hibernate/annotations/common/reflection/XClass.java
index 384537d..9c9b7b2 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/XClass.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/XClass.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection;
 
@@ -52,6 +35,11 @@ public interface XClass extends XAnnotatedElement {
 	 */
 	XClass getSuperclass();
 
+	/**
+	 * The containing class or package
+	 */
+	XAnnotatedElement getContainingElement();
+
 	/**
 	 * @see Class#getInterfaces()
 	 */
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/XMember.java b/src/main/java/org/hibernate/annotations/common/reflection/XMember.java
index f65149e..43d09de 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/XMember.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/XMember.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection;
 
@@ -30,6 +13,13 @@ import java.util.Collection;
  */
 public abstract interface XMember extends XAnnotatedElement {
 
+	/**
+	 * Retrieve the XClass reference for the class which declares this member.
+	 *
+	 * @return The XClass representing the declaring class of the underlying member
+	 */
+	public XClass getDeclaringClass();
+
 	String getName();
 
 	boolean isCollection();
@@ -74,5 +64,13 @@ public abstract interface XMember extends XAnnotatedElement {
 
 	public Object invoke(Object target, Object... parameters);
 
+	/**
+	 * Invoke the method with no parameters.
+	 * Same as {@link #invoke(Object, Object...)}.
+	 * @param target
+	 * @return
+	 */
+	public Object invoke(Object target);
+
 	boolean isTypeResolved();
 }
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/XMethod.java b/src/main/java/org/hibernate/annotations/common/reflection/XMethod.java
index afdb38a..4ef684d 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/XMethod.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/XMethod.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection;
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/XPackage.java b/src/main/java/org/hibernate/annotations/common/reflection/XPackage.java
index 101e8fa..285ccc0 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/XPackage.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/XPackage.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection;
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/XProperty.java b/src/main/java/org/hibernate/annotations/common/reflection/XProperty.java
index 28ff25f..074fe7b 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/XProperty.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/XProperty.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection;
 
@@ -36,9 +19,4 @@ package org.hibernate.annotations.common.reflection;
  * @author Emmanuel Bernard
  */
 public interface XProperty extends XMember {
-
-	/**
-	 * Unqualify the getter name
-	 */
-	String getName();
 }
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaAnnotationReader.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaAnnotationReader.java
index 74b3d0b..5a1a7e7 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaAnnotationReader.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaAnnotationReader.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java;
 
@@ -34,7 +17,7 @@ import org.hibernate.annotations.common.reflection.AnnotationReader;
  * @author Paolo Perrotta
  * @author Davide Marchignoli
  */
-class JavaAnnotationReader implements AnnotationReader {
+final class JavaAnnotationReader implements AnnotationReader {
 
 	protected final AnnotatedElement element;
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaMetadataProvider.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaMetadataProvider.java
index 8b8d067..a7a8d11 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaMetadataProvider.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaMetadataProvider.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.reflection.java;
 
 import java.util.Map;
@@ -10,7 +16,7 @@ import org.hibernate.annotations.common.reflection.AnnotationReader;
 /**
  * @author Emmanuel Bernard
 */
-public class JavaMetadataProvider implements MetadataProvider {
+public final class JavaMetadataProvider implements MetadataProvider {
 
 	public Map<Object, Object> getDefaults() {
 		return Collections.emptyMap();
@@ -19,4 +25,10 @@ public class JavaMetadataProvider implements MetadataProvider {
 	public AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement) {
 		return new JavaAnnotationReader(annotatedElement);
 	}
+
+	@Override
+	public void reset() {
+		//no-op
+	}
+
 }
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java
index ace5e4f..39e62ee 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java;
 
@@ -30,22 +13,21 @@ import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.hibernate.annotations.common.reflection.AnnotationReader;
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
 import org.hibernate.annotations.common.reflection.ReflectionManager;
 import org.hibernate.annotations.common.reflection.XClass;
 import org.hibernate.annotations.common.reflection.XMethod;
 import org.hibernate.annotations.common.reflection.XPackage;
 import org.hibernate.annotations.common.reflection.XProperty;
-import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
-import org.hibernate.annotations.common.reflection.MetadataProvider;
 import org.hibernate.annotations.common.reflection.java.generics.IdentityTypeEnvironment;
 import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironment;
 import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironmentFactory;
 import org.hibernate.annotations.common.reflection.java.generics.TypeSwitch;
 import org.hibernate.annotations.common.reflection.java.generics.TypeUtils;
-import org.hibernate.annotations.common.Version;
-import org.hibernate.annotations.common.util.ReflectHelper;
 
 /**
  * The factory for all the objects in this package.
@@ -53,11 +35,16 @@ import org.hibernate.annotations.common.util.ReflectHelper;
  * @author Paolo Perrotta
  * @author Davide Marchignoli
  * @author Emmanuel Bernard
+ * @author Sanne Grinovero
  */
-public class JavaReflectionManager implements ReflectionManager, MetadataProviderInjector {
+public final class JavaReflectionManager implements ReflectionManager, MetadataProviderInjector {
+
+	private static final boolean METADATA_CACHE_DIAGNOSTICS = Boolean.getBoolean( "org.hibernate.annotations.common.METADATA_CACHE_DIAGNOSTICS" );
 
 	private MetadataProvider metadataProvider;
 
+	private final AtomicBoolean empty = new AtomicBoolean(true);
+
 	public MetadataProvider getMetadataProvider() {
 		if (metadataProvider == null) {
 			setMetadataProvider( new JavaMetadataProvider() );
@@ -69,31 +56,30 @@ public class JavaReflectionManager implements ReflectionManager, MetadataProvide
 		this.metadataProvider = metadataProvider;
 	}
 
-	static {
-		Version.touch();
-	}
+	private final TypeEnvironmentMap<Class,JavaXClass> xClasses = new TypeEnvironmentMap<>( this::javaXClassConstruction );
 
-	private static class TypeKey extends Pair<Type, TypeEnvironment> {
-		TypeKey(Type t, TypeEnvironment context) {
-			super( t, context );
-		}
+	private JavaXClass javaXClassConstruction(
+			Class classType,
+			TypeEnvironment typeEnvironment) {
+		used();
+		return new JavaXClass( classType, typeEnvironment, this );
 	}
 
-	private static class MemberKey extends Pair<Member, TypeEnvironment> {
-		MemberKey(Member member, TypeEnvironment context) {
-			super( member, context );
-		}
-	}
-
-	private final Map<TypeKey, JavaXClass> xClasses = new HashMap<TypeKey, JavaXClass>();
+	private Map<Package, JavaXPackage> packagesToXPackages;
 
-	private final Map<Package, JavaXPackage> packagesToXPackages = new HashMap<Package, JavaXPackage>();
+	private final TypeEnvironmentMap<Member, JavaXProperty> xProperties = new TypeEnvironmentMap<>( this::javaXPropertyConstruction );
 
-	private final Map<MemberKey, JavaXProperty> xProperties = new HashMap<MemberKey, JavaXProperty>();
+	private JavaXProperty javaXPropertyConstruction(Member member, TypeEnvironment typeEnvironment) {
+		used();
+		return JavaXProperty.create( member, typeEnvironment, this );
+	}
 
-	private final Map<MemberKey, JavaXMethod> xMethods = new HashMap<MemberKey, JavaXMethod>();
+	private final TypeEnvironmentMap<Member, JavaXMethod> xMethods = new TypeEnvironmentMap<>( this::javaJavaXMethodConstruction );
 
-	private final TypeEnvironmentFactory typeEnvs = new TypeEnvironmentFactory();
+	private JavaXMethod javaJavaXMethodConstruction(Member member, TypeEnvironment typeEnvironment) {
+		used();
+		return JavaXMethod.create( member, typeEnvironment, this );
+	}
 
 	public XClass toXClass(Class clazz) {
 		return toXClass( clazz, IdentityTypeEnvironment.INSTANCE );
@@ -113,77 +99,59 @@ public class JavaReflectionManager implements ReflectionManager, MetadataProvide
 		return (Method) ( (JavaXAnnotatedElement) xMethod ).toAnnotatedElement();
 	}
 
-	public XClass classForName(String name, Class caller) throws ClassNotFoundException {
-		return toXClass( ReflectHelper.classForName( name, caller ) );
-	}
-
-	public XPackage packageForName(String packageName) throws ClassNotFoundException {
-		return getXAnnotatedElement( ReflectHelper.classForName( packageName + ".package-info" ).getPackage() );
-	}
-
 	XClass toXClass(Type t, final TypeEnvironment context) {
 		return new TypeSwitch<XClass>() {
 			@Override
 			public XClass caseClass(Class classType) {
-				TypeKey key = new TypeKey( classType, context );
-				JavaXClass result = xClasses.get( key );
-				if ( result == null ) {
-					result = new JavaXClass( classType, context, JavaReflectionManager.this );
-					xClasses.put( key, result );
-				}
-				return result;
+				return xClasses.getOrCompute( context, classType );
 			}
 
 			@Override
 			public XClass caseParameterizedType(ParameterizedType parameterizedType) {
 				return toXClass( parameterizedType.getRawType(),
-						typeEnvs.getEnvironment( parameterizedType, context )
+					TypeEnvironmentFactory.getEnvironment( parameterizedType, context )
 				);
 			}
 		}.doSwitch( context.bind( t ) );
 	}
 
-	XPackage getXAnnotatedElement(Package pkg) {
-		JavaXPackage xPackage = packagesToXPackages.get( pkg );
+	@Override
+	public XPackage toXPackage(Package pkg) {
+		final Map<Package, JavaXPackage> packagesToXPackagesMap = getPackagesToXPackagesMap();
+		JavaXPackage xPackage = packagesToXPackagesMap.get( pkg );
 		if ( xPackage == null ) {
 			xPackage = new JavaXPackage( pkg, this );
-			packagesToXPackages.put( pkg, xPackage );
+			used();
+			packagesToXPackagesMap.put( pkg, xPackage );
 		}
 		return xPackage;
 	}
 
-	XProperty getXProperty(Member member, TypeEnvironment context) {
-		MemberKey key = new MemberKey( member, context );
-        //FIXME get is as expensive as create most time spent in hashCode and equals
-        JavaXProperty xProperty = xProperties.get( key );
-		if ( xProperty == null ) {
-			xProperty = JavaXProperty.create( member, context, this );
-			xProperties.put( key, xProperty );
+	private Map<Package, JavaXPackage> getPackagesToXPackagesMap() {
+		if ( this.packagesToXPackages == null ) {
+			this.packagesToXPackages = new HashMap<>( 8, 0.5f );
 		}
-		return xProperty;
+		return this.packagesToXPackages;
+	}
+
+	XProperty getXProperty(Member member, TypeEnvironment context) {
+		return xProperties.getOrCompute( context, member );
 	}
 
 	XMethod getXMethod(Member member, TypeEnvironment context) {
-		MemberKey key = new MemberKey( member, context );
-        //FIXME get is as expensive as create most time spent in hashCode and equals
-        JavaXMethod xMethod = xMethods.get( key );
-		if ( xMethod == null ) {
-			xMethod = JavaXMethod.create( member, context, this );
-			xMethods.put( key, xMethod );
-		}
-		return xMethod;
+		return xMethods.getOrCompute( context, member );
 	}
 
 	TypeEnvironment getTypeEnvironment(final Type t) {
 		return new TypeSwitch<TypeEnvironment>() {
 			@Override
 			public TypeEnvironment caseClass(Class classType) {
-				return typeEnvs.getEnvironment( classType );
+				return TypeEnvironmentFactory.getEnvironment( classType );
 			}
 
 			@Override
 			public TypeEnvironment caseParameterizedType(ParameterizedType parameterizedType) {
-				return typeEnvs.getEnvironment( parameterizedType );
+				return TypeEnvironmentFactory.getEnvironment( parameterizedType );
 			}
 
 			@Override
@@ -207,6 +175,37 @@ public class JavaReflectionManager implements ReflectionManager, MetadataProvide
 		throw new IllegalArgumentException( "No PropertyTypeExtractor available for type void " );
 	}
 
+	@Override
+	public Type toType(XClass xClazz) {
+		if ( ! ( xClazz instanceof JavaXClass ) ) {
+			throw new IllegalArgumentException( "XClass not coming from this ReflectionManager implementation" );
+		}
+		final JavaXClass javaXClazz = (JavaXClass) xClazz;
+		final Class<?> clazz = javaXClazz.toClass();
+		final Type[] typeArguments = clazz.getTypeParameters();
+		if ( typeArguments.length == 0 ) {
+			return clazz;
+		}
+		return javaXClazz.getTypeEnvironment().bind(
+			new ParameterizedType() {
+				@Override
+				public Type[] getActualTypeArguments() {
+					return typeArguments;
+				}
+
+				@Override
+				public Type getRawType() {
+					return clazz;
+				}
+
+				@Override
+				public Type getOwnerType() {
+					return null;
+				}
+			}
+		);
+	}
+
 	public boolean equals(XClass class1, Class class2) {
 		if ( class1 == null ) {
 			return class2 == null;
@@ -215,7 +214,7 @@ public class JavaReflectionManager implements ReflectionManager, MetadataProvide
 	}
 
 	public TypeEnvironment toApproximatingEnvironment(TypeEnvironment context) {
-		return typeEnvs.toApproximatingEnvironment( context );
+		return TypeEnvironmentFactory.toApproximatingEnvironment( context );
 	}
 
     public AnnotationReader buildAnnotationReader(AnnotatedElement annotatedElement) {
@@ -226,4 +225,28 @@ public class JavaReflectionManager implements ReflectionManager, MetadataProvide
         return getMetadataProvider().getDefaults();
     }
 
+	@Override
+	public void reset() {
+		boolean wasEmpty = empty.getAndSet( true );
+		if ( !wasEmpty ) {
+			this.xClasses.clear();
+			this.packagesToXPackages = null;
+			this.xProperties.clear();
+			this.xMethods.clear();
+			if ( METADATA_CACHE_DIAGNOSTICS ) {
+				new RuntimeException( "Diagnostics message : Caches now empty" ).printStackTrace();
+			}
+		}
+		if ( metadataProvider != null ) {
+			this.metadataProvider.reset();
+		}
+	}
+
+	private void used() {
+		boolean wasEmpty = empty.getAndSet( false );
+		if ( wasEmpty && METADATA_CACHE_DIAGNOSTICS ) {
+			new RuntimeException( "Diagnostics message : Caches now being used" ).printStackTrace();
+		}
+	}
+
 }
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXAnnotatedElement.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXAnnotatedElement.java
index eeadade..6b3bfb1 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXAnnotatedElement.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXAnnotatedElement.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java;
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXArrayType.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXArrayType.java
index 24a43fe..88fc316 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXArrayType.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXArrayType.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java;
 
@@ -36,7 +19,7 @@ import org.hibernate.annotations.common.reflection.java.generics.TypeSwitch;
  * @author Emmanuel Bernard
  * @author Paolo Perrotta
  */
-class JavaXArrayType extends JavaXType {
+final class JavaXArrayType extends JavaXType {
 
 	public JavaXArrayType(Type type, TypeEnvironment context, JavaReflectionManager factory) {
 		super( type, context, factory );
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXClass.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXClass.java
index c519705..f428cf4 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXClass.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXClass.java
@@ -1,36 +1,20 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.util.LinkedList;
+import java.util.ArrayList;
 import java.util.List;
 
 import org.hibernate.annotations.common.reflection.Filter;
 import org.hibernate.annotations.common.reflection.ReflectionUtil;
+import org.hibernate.annotations.common.reflection.XAnnotatedElement;
 import org.hibernate.annotations.common.reflection.XClass;
 import org.hibernate.annotations.common.reflection.XMethod;
 import org.hibernate.annotations.common.reflection.XProperty;
@@ -41,7 +25,7 @@ import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironment
  * @author Paolo Perrotta
  * @author Davide Marchignoli
  */
-class JavaXClass extends JavaXAnnotatedElement implements XClass {
+final class JavaXClass extends JavaXAnnotatedElement implements XClass {
 
 	private final TypeEnvironment context;
     private final Class clazz;
@@ -65,6 +49,22 @@ class JavaXClass extends JavaXAnnotatedElement implements XClass {
 		);
 	}
 
+	@Override
+	public XAnnotatedElement getContainingElement() {
+		Class<?> enclosingClass = toClass().getEnclosingClass();
+		if ( enclosingClass != null ) {
+			return getFactory().toXClass( enclosingClass,
+					CompoundTypeEnvironment.create(
+							getTypeEnvironment(),
+							getFactory().getTypeEnvironment( toClass() )
+					)
+			);
+		}
+		else {
+			return getFactory().toXPackage( toClass().getPackage() );
+		}
+	}
+
 	public XClass[] getInterfaces() {
 		Class[] classes = toClass().getInterfaces();
 		int length = classes.length;
@@ -98,22 +98,26 @@ class JavaXClass extends JavaXAnnotatedElement implements XClass {
 	}
 
 	private List<XProperty> getDeclaredFieldProperties(Filter filter) {
-		List<XProperty> result = new LinkedList<XProperty>();
-		for ( Field f : toClass().getDeclaredFields() ) {
+		Field[] declaredFields = toClass().getDeclaredFields();
+		ArrayList<XProperty> result = new ArrayList<>();
+		for ( Field f : declaredFields ) {
 			if ( ReflectionUtil.isProperty( f, getTypeEnvironment().bind( f.getGenericType() ), filter ) ) {
 				result.add( getFactory().getXProperty( f, getTypeEnvironment() ) );
 			}
 		}
+		result.trimToSize();
 		return result;
 	}
 
 	private List<XProperty> getDeclaredMethodProperties(Filter filter) {
-		List<XProperty> result = new LinkedList<XProperty>();
-		for ( Method m : toClass().getDeclaredMethods() ) {
+		ArrayList<XProperty> result = new ArrayList<XProperty>();
+		Method[] declaredMethods = toClass().getDeclaredMethods();
+		for ( Method m : declaredMethods ) {
 			if ( ReflectionUtil.isProperty( m, getTypeEnvironment().bind( m.getGenericReturnType() ), filter ) ) {
 				result.add( getFactory().getXProperty( m, getTypeEnvironment() ) );
 			}
 		}
+		result.trimToSize();
 		return result;
 	}
 
@@ -132,8 +136,9 @@ class JavaXClass extends JavaXAnnotatedElement implements XClass {
 	}
 
 	public List<XMethod> getDeclaredMethods() {
-		List<XMethod> result = new LinkedList<XMethod>();
-		for ( Method m : toClass().getDeclaredMethods() ) {
+		Method[] declaredMethods = toClass().getDeclaredMethods();
+		List<XMethod> result = new ArrayList<>( declaredMethods.length );
+		for ( Method m : declaredMethods ) {
 			result.add( getFactory().getXMethod( m, getTypeEnvironment() ) );
 		}
 		return result;
@@ -159,4 +164,4 @@ class JavaXClass extends JavaXAnnotatedElement implements XClass {
     public String toString() {
         return getName();
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXCollectionType.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXCollectionType.java
index e93d1f2..bc2fdad 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXCollectionType.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXCollectionType.java
@@ -1,28 +1,11 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 
-// $Id: JavaXCollectionType.java 15416 2008-10-28 18:43:14Z steve.ebersole@jboss.com $
+// $Id$
 package org.hibernate.annotations.common.reflection.java;
 
 import java.lang.reflect.ParameterizedType;
@@ -41,7 +24,7 @@ import org.hibernate.annotations.common.reflection.java.generics.TypeUtils;
  * @author Paolo Perrotta
  */
 @SuppressWarnings("unchecked")
-class JavaXCollectionType extends JavaXType {
+final class JavaXCollectionType extends JavaXType {
 
 	public JavaXCollectionType(Type type, TypeEnvironment context, JavaReflectionManager factory) {
 		super( type, context, factory );
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXMember.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXMember.java
index 204ae37..799bd00 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXMember.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXMember.java
@@ -1,28 +1,11 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 
-//$Id: JavaXMember.java 15416 2008-10-28 18:43:14Z steve.ebersole@jboss.com $
+//$Id$
 package org.hibernate.annotations.common.reflection.java;
 
 import java.lang.reflect.AccessibleObject;
@@ -68,7 +51,7 @@ public abstract class JavaXMember extends JavaXAnnotatedElement implements XMemb
 
 	public abstract String getName();
 
-	protected Type getJavaType() {
+	public Type getJavaType() {
 		return env.bind( type );
 	}
 
@@ -76,10 +59,15 @@ public abstract class JavaXMember extends JavaXAnnotatedElement implements XMemb
 		return env;
 	}
 
-	protected Member getMember() {
+	public Member getMember() {
 		return (Member) toAnnotatedElement();
 	}
 
+	@Override
+	public XClass getDeclaringClass() {
+		return getFactory().toXClass( getMember().getDeclaringClass() );
+	}
+
 	public Class<? extends Collection> getCollectionClass() {
 		return xType.getCollectionClass();
 	}
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXMethod.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXMethod.java
index 7e1d8c4..a7a6373 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXMethod.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXMethod.java
@@ -1,28 +1,11 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 
-//$Id: JavaXMethod.java 15416 2008-10-28 18:43:14Z steve.ebersole@jboss.com $
+//$Id$
 package org.hibernate.annotations.common.reflection.java;
 
 import java.lang.reflect.Member;
@@ -35,7 +18,9 @@ import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironment
 /**
  * @author Emmanuel Bernard
  */
-public class JavaXMethod extends JavaXMember implements XMethod {
+final public class JavaXMethod extends JavaXMember implements XMethod {
+
+	private static final Object[] EMPTY_ARRAY = new Object[0];
 
 	static JavaXMethod create(Member member, TypeEnvironment context, JavaReflectionManager factory) {
 		final Type propType = typeOf( member, context );
@@ -48,10 +33,17 @@ public class JavaXMethod extends JavaXMember implements XMethod {
 		assert member instanceof Method;
 	}
 
+	@Override
 	public String getName() {
 		return getMember().getName();
 	}
 
+	@Override
+	public Object invoke(Object target) {
+		return invoke( target, EMPTY_ARRAY );
+	}
+
+	@Override
 	public Object invoke(Object target, Object... parameters) {
 		try {
 			return ( (Method) getMember() ).invoke( target, parameters );
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXPackage.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXPackage.java
index 4e1409d..1dbbc8a 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXPackage.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXPackage.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java;
 
@@ -29,7 +12,7 @@ import org.hibernate.annotations.common.reflection.XPackage;
  * @author Paolo Perrotta
  * @author Davide Marchignoli
  */
-class JavaXPackage extends JavaXAnnotatedElement implements XPackage {
+final class JavaXPackage extends JavaXAnnotatedElement implements XPackage {
 
 	public JavaXPackage(Package pkg, JavaReflectionManager factory) {
 		super( pkg, factory );
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXProperty.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXProperty.java
index 4c5618e..b4e62d9 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXProperty.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXProperty.java
@@ -1,29 +1,11 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java;
 
-import java.beans.Introspector;
 import java.lang.reflect.Field;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
@@ -36,7 +18,9 @@ import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironment
  * @author Paolo Perrotta
  * @author Davide Marchignoli
  */
-class JavaXProperty extends JavaXMember implements XProperty {
+final class JavaXProperty extends JavaXMember implements XProperty {
+
+	private static final Object[] EMPTY_ARRAY = new Object[0];
 
 	static JavaXProperty create(Member member, final TypeEnvironment context, final JavaReflectionManager factory) {
 		final Type propType = typeOf( member, context );
@@ -53,10 +37,10 @@ class JavaXProperty extends JavaXMember implements XProperty {
 		String fullName = getMember().getName();
 		if ( getMember() instanceof Method ) {
 			if ( fullName.startsWith( "get" ) ) {
-				return Introspector.decapitalize( fullName.substring( "get".length() ) );
+				return decapitalize( fullName.substring( "get".length() ) );
 			}
 			if ( fullName.startsWith( "is" ) ) {
-				return Introspector.decapitalize( fullName.substring( "is".length() ) );
+				return decapitalize( fullName.substring( "is".length() ) );
 			}
 			throw new RuntimeException( "Method " + fullName + " is not a property getter" );
 		}
@@ -65,16 +49,56 @@ class JavaXProperty extends JavaXMember implements XProperty {
 		}
 	}
 
-	public Object invoke(Object target, Object... parameters) {
-		if ( parameters.length != 0 ) {
-			throw new IllegalArgumentException( "An XProperty cannot have invoke parameters" );
+	// See conventions expressed by https://docs.oracle.com/javase/7/docs/api/java/beans/Introspector.html#decapitalize(java.lang.String)
+	private static String decapitalize(String name) {
+		if (name != null && name.length() != 0) {
+			if (name.length() > 1 && Character.isUpperCase(name.charAt(1))) {
+				return name;
+			} else {
+				char[] chars = name.toCharArray();
+				chars[0] = Character.toLowerCase(chars[0]);
+				return new String(chars);
+			}
+		} else {
+			return name;
 		}
+	}
+
+	@Override
+	public Object invoke(Object target) {
+		//Implementation note: only #invoke(Object target, Object... parameters)
+		//existed until HCANN 5.0.0.Final, but it turned out to be a performance issue as that would cause
+		//each invocation to allocate an empty array to pass as vararg.
 		try {
 			if ( getMember() instanceof Method ) {
-				return ( (Method) getMember() ).invoke( target );
+				return ( (Method) getMember() ).invoke( target, EMPTY_ARRAY );
 			}
 			else {
-				return ( (Field) getMember() ).get( target );
+				Field field = (Field) getMember();
+				// This is needed because until JDK 9 the Reflection API
+				// does not use the same caching as used for auto-boxing.
+				// See https://bugs.openjdk.java.net/browse/JDK-5043030 for details.
+				// The code below can be removed when we move to JDK 9.
+				// double and float are intentionally not handled here because
+				// the JLS § 5.1.7 does not define caching for boxed values of
+				// this types.
+				Class<?> type = field.getType();
+				if ( type.isPrimitive() ) {
+					if ( type == Boolean.TYPE ) {
+						return Boolean.valueOf( field.getBoolean( target ) );
+					} else if ( type == Byte.TYPE ) {
+						return Byte.valueOf( field.getByte( target ) );
+					} else if ( type == Character.TYPE ) {
+						return Character.valueOf( field.getChar( target ) );
+					} else if ( type == Integer.TYPE ) {
+						return Integer.valueOf( field.getInt( target ) );
+					} else if ( type == Long.TYPE ) {
+						return Long.valueOf( field.getLong( target ) );
+					} else if ( type == Short.TYPE ) {
+						return Short.valueOf( field.getShort( target ) );
+					}
+				}
+				return field.get( target );
 			}
 		}
 		catch (NullPointerException e) {
@@ -88,8 +112,16 @@ class JavaXProperty extends JavaXMember implements XProperty {
 		}
 	}
 
+	@Override
+	public Object invoke(Object target, Object... parameters) {
+		if ( parameters.length != 0 ) {
+			throw new IllegalArgumentException( "An XProperty cannot have invoke parameters" );
+		}
+		return invoke( target );
+	}
+
 	@Override
 	public String toString() {
 		return getName();
 	}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXSimpleType.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXSimpleType.java
index 57878c5..46738bc 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXSimpleType.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXSimpleType.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java;
 
@@ -33,7 +16,7 @@ import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironment
  * @author Emmanuel Bernard
  * @author Paolo Perrotta
  */
-class JavaXSimpleType extends JavaXType {
+final class JavaXSimpleType extends JavaXType {
 
 	public JavaXSimpleType(Type type, TypeEnvironment context, JavaReflectionManager factory) {
 		super( type, context, factory );
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXType.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXType.java
index 137e9c0..126a60d 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXType.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXType.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 
 //$Id: PropertyTypeExtractor.java 9316 2006-02-22 20:47:31Z epbernard $
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/Pair.java b/src/main/java/org/hibernate/annotations/common/reflection/java/Pair.java
deleted file mode 100644
index 97c3519..0000000
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/Pair.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, 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.annotations.common.reflection.java;
-
-/**
- * A pair of objects that can be used as a key in a Map.
- *
- * @author Paolo Perrotta
- * @author Davide Marchignoli
- */
-abstract class Pair<T, U> {
-
-	private final T o1;
-
-	private final U o2;
-    private final int hashCode;
-
-    Pair(T o1, U o2) {
-		this.o1 = o1;
-		this.o2 = o2;
-        this.hashCode = doHashCode();
-    }
-
-	@Override
-	public boolean equals(Object obj) {
-		if ( ! (obj instanceof Pair) ) {
-			 return false;
-		}
-		Pair other = (Pair) obj;
-        return !differentHashCode( other ) && safeEquals( o1, other.o1 ) && safeEquals( o2, other.o2 );
-    }
-
-    private boolean differentHashCode(Pair other) {
-        return hashCode != other.hashCode;
-    }
-
-    @Override
-	public int hashCode() {
-        //cached because the inheritance can be big
-        return hashCode;
-	}
-
-    private int doHashCode() {
-		return safeHashCode( o1 ) ^ safeHashCode( o2 );
-	}
-
-	private int safeHashCode(Object o) {
-		if ( o == null ) {
-			return 0;
-		}
-		return o.hashCode();
-	}
-
-	private boolean safeEquals(Object obj1, Object obj2) {
-		if ( obj1 == null ) {
-			return obj2 == null;
-		}
-        return obj1.equals( obj2 );
-	}
-}
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/TypeEnvironmentMap.java b/src/main/java/org/hibernate/annotations/common/reflection/java/TypeEnvironmentMap.java
new file mode 100644
index 0000000..ed4bd1f
--- /dev/null
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/TypeEnvironmentMap.java
@@ -0,0 +1,82 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
+package org.hibernate.annotations.common.reflection.java;
+
+import java.util.HashMap;
+import java.util.Objects;
+
+import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironment;
+
+/**
+ * We need a two-level sparse tree for best efficiency in this case;
+ * the first split uses TypeEnvironment as a key, under which we store
+ * an additional Map to further organize by K.
+ * This used to be implemented as a HashMap with a composite key {TypeEnvironment,K},
+ * but this wasn't memory efficient as all composite keys take too much space:
+ * the nested structure has some overhead as well, but has been shown to cost less
+ * overall.
+ * In addition, we strife to not need to compute hashkeys multiple times while
+ * not needing to allocate stateful lambdas; for this reason the tree nodes
+ * need to store some additional references.
+ * 
+ * @param <K>
+ * @param <V>
+ * @author Sanne Grinovero
+ */
+final class TypeEnvironmentMap<K,V> {
+
+	//First level is optimised for fast access; it's expected to be small so a low load factor
+	//should be fine in terms of memory costs.
+	private HashMap<TypeEnvironment, ContextScope> rootMap;
+	private final XTypeConstruction<K,V> constructionMethod;
+
+	TypeEnvironmentMap(final XTypeConstruction<K, V> constructionMethod) {
+		Objects.requireNonNull( constructionMethod );
+		this.constructionMethod = constructionMethod;
+	}
+
+	private <K, V> HashMap<TypeEnvironment, ContextScope> getOrInitRootMap() {
+		if ( this.rootMap == null ) {
+			this.rootMap = new HashMap<>( 8, 0.5f );
+		}
+		return this.rootMap;
+	}
+
+	V getOrCompute(final TypeEnvironment context, final K subKey) {
+		final ContextScope contextualMap = getOrInitRootMap().computeIfAbsent( context, ContextScope::new );
+		return contextualMap.getOrCompute( subKey );
+	}
+
+	void clear() {
+		final HashMap<TypeEnvironment, ContextScope> m = this.rootMap;
+		if ( m != null ) {
+			// Remove the reference to the rootMap, as very large arrays within HashMap
+			// are not resized when clearing.
+			this.rootMap = null;
+			m.clear();
+		}
+	}
+
+	private final class ContextScope extends HashMap<K,V> {
+
+		private final TypeEnvironment context;
+
+		private ContextScope(TypeEnvironment context) {
+			//In the second level of the tree we expect many entries, but we can't have it consume too much memory:
+			super( 64, 0.85f );
+			this.context = context;
+		}
+
+		private V getOrCompute(K subKey) {
+			return computeIfAbsent( subKey, this::buildObject );
+		}
+
+		private V buildObject(K subKey) {
+			return constructionMethod.createInstance( subKey, context );
+		}
+	}
+}
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/XTypeConstruction.java b/src/main/java/org/hibernate/annotations/common/reflection/java/XTypeConstruction.java
new file mode 100644
index 0000000..0bb6087
--- /dev/null
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/XTypeConstruction.java
@@ -0,0 +1,16 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
+package org.hibernate.annotations.common.reflection.java;
+
+import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironment;
+
+@FunctionalInterface
+interface XTypeConstruction<K,V> {
+
+	V createInstance(K typeKey, TypeEnvironment context);
+
+}
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/ApproximatingTypeEnvironment.java b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/ApproximatingTypeEnvironment.java
index 2480eb5..9614cbc 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/ApproximatingTypeEnvironment.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/ApproximatingTypeEnvironment.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java.generics;
 
@@ -60,7 +43,7 @@ import java.lang.reflect.WildcardType;
  * @author Paolo Perrotta
  * @return a type where the generic arguments have been replaced by raw classes.
  */
-class ApproximatingTypeEnvironment implements TypeEnvironment {
+final class ApproximatingTypeEnvironment implements TypeEnvironment {
 
 	public Type bind(final Type type) {
 		Type result = fineApproximation( type );
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/CompoundTypeEnvironment.java b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/CompoundTypeEnvironment.java
index 58a183a..df87e99 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/CompoundTypeEnvironment.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/CompoundTypeEnvironment.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java.generics;
 
@@ -31,12 +14,10 @@ import java.lang.reflect.Type;
  * @author Davide Marchignoli
  * @author Paolo Perrotta
  */
-public class CompoundTypeEnvironment implements TypeEnvironment {
+public final class CompoundTypeEnvironment implements TypeEnvironment {
 
 	private final TypeEnvironment f;
-
 	private final TypeEnvironment g;
-    
     private final int hashCode;
 
     public static TypeEnvironment create(TypeEnvironment f, TypeEnvironment g) {
@@ -50,7 +31,7 @@ public class CompoundTypeEnvironment implements TypeEnvironment {
     private CompoundTypeEnvironment(TypeEnvironment f, TypeEnvironment g) {
 		this.f = f;
 		this.g = g;
-        hashCode = doHashCode();
+        this.hashCode = doHashCode( f, g );
     }
 
 	public Type bind(Type type) {
@@ -67,14 +48,15 @@ public class CompoundTypeEnvironment implements TypeEnvironment {
 
         if ( !f.equals( that.f ) ) return false;
         return g.equals( that.g );
-
     }
 
     private boolean differentHashCode(CompoundTypeEnvironment that) {
         return hashCode != that.hashCode;
     }
 
-    private int doHashCode() {
+    private static int doHashCode(
+			TypeEnvironment f,
+			TypeEnvironment g) {
 		int result;
 		result = f.hashCode();
 		result = 29 * result + g.hashCode();
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/IdentityTypeEnvironment.java b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/IdentityTypeEnvironment.java
index b4a826e..b40dcdf 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/IdentityTypeEnvironment.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/IdentityTypeEnvironment.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java.generics;
 
@@ -31,7 +14,7 @@ import java.lang.reflect.Type;
  * @author Davide Marchignoli
  * @author Paolo Perrotta
  */
-public class IdentityTypeEnvironment implements TypeEnvironment {
+public final class IdentityTypeEnvironment implements TypeEnvironment {
 
 	public static final TypeEnvironment INSTANCE = new IdentityTypeEnvironment();
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/SimpleTypeEnvironment.java b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/SimpleTypeEnvironment.java
index 3a4ed1a..0af3ad7 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/SimpleTypeEnvironment.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/SimpleTypeEnvironment.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java.generics;
 
@@ -29,6 +12,7 @@ import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 import java.lang.reflect.WildcardType;
 import java.util.HashMap;
+import java.util.Objects;
 
 /**
  * Binds formal type arguments (typically T, E, etc.) to actual types.
@@ -36,11 +20,11 @@ import java.util.HashMap;
  * @author Davide Marchignoli
  * @author Paolo Perrotta
  */
-class SimpleTypeEnvironment extends HashMap<Type, Type> implements TypeEnvironment {
+final class SimpleTypeEnvironment implements TypeEnvironment {
 
-	private static final long serialVersionUID = 1L;
-    
-    private final TypeSwitch<Type> substitute = new TypeSwitch<Type>() {
+	private final HashMap<Type, Type> typeMap = new HashMap<>();
+
+	private final TypeSwitch<Type> substitute = new TypeSwitch<Type>() {
 		@Override
 		public Type caseClass(Class classType) {
 			return classType;
@@ -84,10 +68,11 @@ class SimpleTypeEnvironment extends HashMap<Type, Type> implements TypeEnvironme
 
 		@Override
 		public Type caseTypeVariable(TypeVariable typeVariable) {
-            if ( !containsKey( typeVariable )) {
+			final Type type = typeMap.get( typeVariable );
+			if ( type == null ) {
             	return typeVariable;
             }
-            return get( typeVariable );
+            return type;
 		}
 
 		@Override
@@ -97,8 +82,8 @@ class SimpleTypeEnvironment extends HashMap<Type, Type> implements TypeEnvironme
 	};
 
 	public SimpleTypeEnvironment(Type[] formalTypeArgs, Type[] actualTypeArgs) {
-        for (int i = 0; i < formalTypeArgs.length; i++) {
-            put( formalTypeArgs[i], actualTypeArgs[i] );
+		for ( int i = 0; i < formalTypeArgs.length; i++ ) {
+			typeMap.put( formalTypeArgs[i], actualTypeArgs[i] );
         }
 	}
 
@@ -113,4 +98,22 @@ class SimpleTypeEnvironment extends HashMap<Type, Type> implements TypeEnvironme
 		}
 		return substTypes;
 	}
+
+	@Override
+	public boolean equals(Object o) {
+		if ( this == o ) {
+			return true;
+		}
+		if ( o == null || SimpleTypeEnvironment.class != o.getClass() ) {
+			return false;
+		}
+		SimpleTypeEnvironment that = (SimpleTypeEnvironment) o;
+		return Objects.equals( typeMap, that.typeMap );
+	}
+
+	@Override
+	public int hashCode() {
+		return Objects.hash( typeMap );
+	}
+
 }
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeEnvironment.java b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeEnvironment.java
index 09fe12c..ce1b6ab 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeEnvironment.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeEnvironment.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java.generics;
 
@@ -30,24 +13,24 @@ import java.lang.reflect.Type;
  * <code>Type</code>.
  * <p/>
  * For example:
- * <p/>
- * <p/>
- * <blockquote>
- * <p/>
  * <pre>
- *  class Shop&ltT&gt{
+ * {@code
+ *  class Shop&ltT&gt {
  *    List&ltT&gt getCatalog() { ... }
  *  }
- * <p/>
- *  class Bakery extends Shop&ltBread&gt{}
+ * }
  * </pre>
  * <p/>
- * </blockquote>
+ * <pre>
+ * {@code
+ * class Bakery extends Shop<Bread> { ... }
+ * }
+ * </pre>
  * <p/>
  * Consider the type returned by method <code>getCatalog()</code>. There are
  * two possible contexts here. In the context of <code>Shop</code>, the type
- * is <code>List&ltT&gt</code>. In the context of <code>Bakery</code>, the
- * type is <code>List&ltBread&gt</code>. Each of these contexts can be
+ * is <code>List<T></code>. In the context of <code>Bakery</code>, the
+ * type is <code>List<Bread></code>. Each of these contexts can be
  * represented by a <code>TypeEnvironment</code>.
  *
  * @author Davide Marchignoli
@@ -73,4 +56,5 @@ public interface TypeEnvironment {
 	 *         classes whenever this is possible.
 	 */
 	public Type bind(Type type);
-}
\ No newline at end of file
+
+}
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeEnvironmentFactory.java b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeEnvironmentFactory.java
index 2aafd19..7847c02 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeEnvironmentFactory.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeEnvironmentFactory.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java.generics;
 
@@ -35,35 +18,39 @@ import java.lang.reflect.TypeVariable;
  * @author Davide Marchignoli
  * @author Paolo Perrotta
  */
-public class TypeEnvironmentFactory {
+public final class TypeEnvironmentFactory {
+
+	private TypeEnvironmentFactory() {
+		//no need to construct
+	}
 
 	/**
 	 * @return Returns a type environment suitable for resolving types occurring
 	 *         in subclasses of the context class.
 	 */
-	public TypeEnvironment getEnvironment(Class context) {
+	public static TypeEnvironment getEnvironment(Class context) {
 		if ( context == null ) {
         	return IdentityTypeEnvironment.INSTANCE;
         }
         return createEnvironment( context );
 	}
 
-	public TypeEnvironment getEnvironment(Type context) {
+	public static TypeEnvironment getEnvironment(Type context) {
 		if ( context == null ) {
         	return IdentityTypeEnvironment.INSTANCE;
         }
         return createEnvironment( context );
 	}
 
-	public TypeEnvironment getEnvironment(Type t, TypeEnvironment context) {
-		return CompoundTypeEnvironment.create( getEnvironment(t), context );
+	public static TypeEnvironment getEnvironment(Type t, TypeEnvironment context) {
+		return CompoundTypeEnvironment.create( getEnvironment( t ), context );
 	}
 
-	public TypeEnvironment toApproximatingEnvironment(TypeEnvironment context) {
+	public static TypeEnvironment toApproximatingEnvironment(TypeEnvironment context) {
 		return CompoundTypeEnvironment.create( new ApproximatingTypeEnvironment(), context );
 	}
 
-	private TypeEnvironment createEnvironment(Type context) {
+	private static TypeEnvironment createEnvironment(Type context) {
 		return new TypeSwitch<TypeEnvironment>() {
 			@Override
 			public TypeEnvironment caseClass(Class classType) {
@@ -85,13 +72,12 @@ public class TypeEnvironmentFactory {
 		}.doSwitch( context );
 	}
 
-	private TypeEnvironment createSuperTypeEnvironment(Class clazz) {
+	private static TypeEnvironment createSuperTypeEnvironment(Class clazz) {
 		Class superclass = clazz.getSuperclass();
 		if ( superclass == null ) {
 			return IdentityTypeEnvironment.INSTANCE;
 		}
 
-		Type[] formalArgs = superclass.getTypeParameters();
 		Type genericSuperclass = clazz.getGenericSuperclass();
 
 		if ( genericSuperclass instanceof Class ) {
@@ -99,6 +85,7 @@ public class TypeEnvironmentFactory {
 		}
 
 		if ( genericSuperclass instanceof ParameterizedType ) {
+			Type[] formalArgs = superclass.getTypeParameters();
 			Type[] actualArgs = ( (ParameterizedType) genericSuperclass ).getActualTypeArguments();
 			return new SimpleTypeEnvironment( formalArgs, actualArgs );
 		}
@@ -106,7 +93,7 @@ public class TypeEnvironmentFactory {
 		throw new AssertionError( "Should be unreachable" );
 	}
 
-	private TypeEnvironment createEnvironment(ParameterizedType t) {
+	private static TypeEnvironment createEnvironment(ParameterizedType t) {
 		Type[] tactuals = t.getActualTypeArguments();
 		Type rawType = t.getRawType();
 		if ( rawType instanceof Class ) {
@@ -115,4 +102,5 @@ public class TypeEnvironmentFactory {
 		}
 		return IdentityTypeEnvironment.INSTANCE;
 	}
+
 }
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeFactory.java b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeFactory.java
index 380b58e..2a79ec5 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeFactory.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeFactory.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java.generics;
 
@@ -28,6 +11,7 @@ import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.Arrays;
+import java.util.StringJoiner;
 
 /**
  * This class instances our own <code>ParameterizedTypes</code> and <code>GenericArrayTypes</code>.
@@ -74,6 +58,42 @@ class TypeFactory {
 						getOwnerType()
 				);
 			}
+
+			@Override
+			public String toString() {
+				final StringBuilder sb = new StringBuilder();
+				if ( ownerType != null ) {
+					sb.append( ownerType.getTypeName() );
+
+					sb.append( "$" );
+
+					if ( ownerType instanceof ParameterizedType ) {
+						// Find simple name of nested type by removing the
+						// shared prefix with owner.
+						sb.append(
+							rawType.getTypeName().replace(
+								( (ParameterizedType) ownerType ).getRawType().getTypeName() + "$",
+								""
+							)
+						);
+					} else if ( rawType instanceof Class<?> ) {
+						sb.append( ( (Class<?>) rawType ).getSimpleName() );
+					} else
+						sb.append( rawType.getTypeName() );
+				} else
+					sb.append( rawType.getTypeName() );
+
+				if ( substTypeArgs != null ) {
+					final StringJoiner sj = new StringJoiner( ", ", "<", ">" );
+					sj.setEmptyValue( "" );
+					for ( Type t : substTypeArgs ) {
+						sj.add( t.getTypeName() );
+					}
+					sb.append( sj );
+				}
+
+				return sb.toString();
+			}
 		};
 	}
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeSwitch.java b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeSwitch.java
index ca9cd76..3d53249 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeSwitch.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeSwitch.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java.generics;
 
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeUtils.java b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeUtils.java
index ec245b0..34c4979 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeUtils.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeUtils.java
@@ -1,25 +1,8 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, 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
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  */
 package org.hibernate.annotations.common.reflection.java.generics;
 
@@ -82,6 +65,7 @@ public class TypeUtils {
 	public static Class<? extends Collection> getCollectionClass(Type type) {
 		return new TypeSwitch<Class<? extends Collection>>() {
 			@Override
+			@SuppressWarnings("unchecked")
 			public Class<? extends Collection> caseClass(Class clazz) {
 				return isCollectionClass( clazz ) ? (Class<? extends Collection>) clazz : null;
 			}
@@ -108,12 +92,8 @@ public class TypeUtils {
 	}
 
 	private static boolean isCollectionClass(Class<?> clazz) {
-		return clazz == Collection.class
-				|| clazz == java.util.List.class
-				|| clazz == java.util.Set.class
-				|| clazz == java.util.Map.class
-				|| clazz == java.util.SortedSet.class // extension to the specs
-				|| clazz == java.util.SortedMap.class; // extension to the specs
+        return Collection.class.isAssignableFrom( clazz)
+                || java.util.Map.class.isAssignableFrom( clazz);
 	}
 
 	public static boolean isSimple(Type type) {
@@ -149,6 +129,7 @@ public class TypeUtils {
 		return true;
 	}
 
+	@SuppressWarnings("EqualsBetweenInconvertibleTypes")
 	public static boolean isVoid(Type type) {
 		return void.class.equals( type );
 	}
diff --git a/src/main/java/org/hibernate/annotations/common/util/ReflectHelper.java b/src/main/java/org/hibernate/annotations/common/util/ReflectHelper.java
deleted file mode 100644
index deaad30..0000000
--- a/src/main/java/org/hibernate/annotations/common/util/ReflectHelper.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, 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.annotations.common.util;
-
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import org.hibernate.annotations.common.AssertionFailure;
-
-/**
- * Complete duplication of {@link org.hibernate.util.ReflectHelper}.
- *
- * @author Emmanuel Bernard
- */
-public final class ReflectHelper {
-
-	public static final Class[] NO_PARAM_SIGNATURE = new Class[0];
-	public static final Object[] NO_PARAMS = new Object[0];
-
-	public static final Class[] SINGLE_OBJECT_PARAM_SIGNATURE = new Class[] { Object.class };
-
-	private static final Method OBJECT_EQUALS;
-	private static final Method OBJECT_HASHCODE;
-
-	static {
-		Method eq;
-		Method hash;
-		try {
-			eq = extractEqualsMethod( Object.class );
-			hash = extractHashCodeMethod( Object.class );
-		}
-		catch ( Exception e ) {
-			throw new AssertionFailure( "Could not find Object.equals() or Object.hashCode()", e );
-		}
-		OBJECT_EQUALS = eq;
-		OBJECT_HASHCODE = hash;
-	}
-
-	/**
-	 * Disallow instantiation of ReflectHelper.
-	 */
-	private ReflectHelper() {
-	}
-
-	/**
-	 * Encapsulation of getting hold of a class's {@link Object#equals equals}  method.
-	 *
-	 * @param clazz The class from which to extract the equals method.
-	 * @return The equals method reference
-	 * @throws NoSuchMethodException Should indicate an attempt to extract equals method from interface.
-	 */
-	public static Method extractEqualsMethod(Class clazz) throws NoSuchMethodException {
-		return clazz.getMethod( "equals", SINGLE_OBJECT_PARAM_SIGNATURE );
-	}
-
-	/**
-	 * Encapsulation of getting hold of a class's {@link Object#hashCode hashCode} method.
-	 *
-	 * @param clazz The class from which to extract the hashCode method.
-	 * @return The hashCode method reference
-	 * @throws NoSuchMethodException Should indicate an attempt to extract hashCode method from interface.
-	 */
-	public static Method extractHashCodeMethod(Class clazz) throws NoSuchMethodException {
-		return clazz.getMethod( "hashCode", NO_PARAM_SIGNATURE );
-	}
-
-	/**
-	 * Determine if the given class defines an {@link Object#equals} override.
-	 *
-	 * @param clazz The class to check
-	 * @return True if clazz defines an equals override.
-	 */
-	public static boolean overridesEquals(Class clazz) {
-		Method equals;
-		try {
-			equals = extractEqualsMethod( clazz );
-		}
-		catch ( NoSuchMethodException nsme ) {
-			return false; //its an interface so we can't really tell anything...
-		}
-		return !OBJECT_EQUALS.equals( equals );
-	}
-
-	/**
-	 * Determine if the given class defines a {@link Object#hashCode} override.
-	 *
-	 * @param clazz The class to check
-	 * @return True if clazz defines an hashCode override.
-	 */
-	public static boolean overridesHashCode(Class clazz) {
-		Method hashCode;
-		try {
-			hashCode = extractHashCodeMethod( clazz );
-		}
-		catch ( NoSuchMethodException nsme ) {
-			return false; //its an interface so we can't really tell anything...
-		}
-		return !OBJECT_HASHCODE.equals( hashCode );
-	}
-
-	/**
-	 * Perform resolution of a class name.
-	 * <p/>
-	 * Here we first check the context classloader, if one, before delegating to
-	 * {@link Class#forName(String, boolean, ClassLoader)} using the caller's classloader
-	 *
-	 * @param name The class name
-	 * @param caller The class from which this call originated (in order to access that class's loader).
-	 * @return The class reference.
-	 * @throws ClassNotFoundException From {@link Class#forName(String, boolean, ClassLoader)}.
-	 */
-	public static Class classForName(String name, Class caller) throws ClassNotFoundException {
-		try {
-			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-			if ( contextClassLoader != null ) {
-				return contextClassLoader.loadClass( name );
-			}
-		}
-		catch ( Throwable ignore ) {
-		}
-		return Class.forName( name, true, caller.getClassLoader() );
-	}
-
-	/**
-	 * Perform resolution of a class name.
-	 * <p/>
-	 * Same as {@link #classForName(String, Class)} except that here we delegate to
-	 * {@link Class#forName(String)} if the context classloader lookup is unsuccessful.
-	 *
-	 * @param name The class name
-	 * @return The class reference.
-	 * @throws ClassNotFoundException From {@link Class#forName(String)}.
-	 */
-	public static Class classForName(String name) throws ClassNotFoundException {
-		try {
-			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-			if ( contextClassLoader != null ) {
-				return contextClassLoader.loadClass(name);
-			}
-		}
-		catch ( Throwable ignore ) {
-		}
-		return Class.forName( name );
-	}
-
-	/**
-	 * Is this member publicly accessible.
-	 *
-	 * @param clazz The class which defines the member
-	 * @param member The memeber.
-	 * @return True if the member is publicly accessible, false otherwise.
-	 */
-	public static boolean isPublic(Class clazz, Member member) {
-		return Modifier.isPublic( member.getModifiers() ) && Modifier.isPublic( clazz.getModifiers() );
-	}
-
-	/**
-	 * Resolve a constant to its actual value.
-	 *
-	 * @param name The name
-	 * @return The value
-	 */
-	public static Object getConstantValue(String name) {
-		Class clazz;
-		try {
-			clazz = classForName( StringHelper.qualifier( name ) );
-		}
-		catch ( Throwable t ) {
-			return null;
-		}
-		try {
-			return clazz.getField( StringHelper.unqualify( name ) ).get( null );
-		}
-		catch ( Throwable t ) {
-			return null;
-		}
-	}
-
-	/**
-	 * Determine if the given class is declared abstract.
-	 *
-	 * @param clazz The class to check.
-	 * @return True if the class is abstract, false otherwise.
-	 */
-	public static boolean isAbstractClass(Class clazz) {
-		int modifier = clazz.getModifiers();
-		return Modifier.isAbstract(modifier) || Modifier.isInterface(modifier);
-	}
-
-	/**
-	 * Determine is the given class is declared final.
-	 *
-	 * @param clazz The class to check.
-	 * @return True if the class is final, flase otherwise.
-	 */
-	public static boolean isFinalClass(Class clazz) {
-		return Modifier.isFinal( clazz.getModifiers() );
-	}
-
-	public static Method getMethod(Class clazz, Method method) {
-		try {
-			return clazz.getMethod( method.getName(), method.getParameterTypes() );
-		}
-		catch (Exception e) {
-			return null;
-		}
-	}
-
-}
-
diff --git a/src/main/java/org/hibernate/annotations/common/util/StringHelper.java b/src/main/java/org/hibernate/annotations/common/util/StringHelper.java
deleted file mode 100644
index a4d17b0..0000000
--- a/src/main/java/org/hibernate/annotations/common/util/StringHelper.java
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, 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.annotations.common.util;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.StringTokenizer;
-
-
-/**
- * Complete duplication of {@link org.hibernate.util.StringHelper}.
- *
- * @author Emmanuel Bernard
- */
-public final class StringHelper {
-
-	private static final int ALIAS_TRUNCATE_LENGTH = 10;
-	public static final String WHITESPACE = " \n\r\f\t";
-
-	private StringHelper() { /* static methods only - hide constructor */
-	}
-
-	/*public static boolean containsDigits(String string) {
-		for ( int i=0; i<string.length(); i++ ) {
-			if ( Character.isDigit( string.charAt(i) ) ) return true;
-		}
-		return false;
-	}*/
-
-	public static int lastIndexOfLetter(String string) {
-		for ( int i=0; i<string.length(); i++ ) {
-			char character = string.charAt(i);
-			if ( !Character.isLetter(character) /*&& !('_'==character)*/ ) return i-1;
-		}
-		return string.length()-1;
-	}
-
-	public static String join(String seperator, String[] strings) {
-		int length = strings.length;
-		if ( length == 0 ) return "";
-		StringBuffer buf = new StringBuffer( length * strings[0].length() )
-				.append( strings[0] );
-		for ( int i = 1; i < length; i++ ) {
-			buf.append( seperator ).append( strings[i] );
-		}
-		return buf.toString();
-	}
-
-	public static String join(String seperator, Iterator objects) {
-		StringBuffer buf = new StringBuffer();
-		if ( objects.hasNext() ) buf.append( objects.next() );
-		while ( objects.hasNext() ) {
-			buf.append( seperator ).append( objects.next() );
-		}
-		return buf.toString();
-	}
-
-	public static String[] add(String[] x, String sep, String[] y) {
-		String[] result = new String[x.length];
-		for ( int i = 0; i < x.length; i++ ) {
-			result[i] = x[i] + sep + y[i];
-		}
-		return result;
-	}
-
-	public static String repeat(String string, int times) {
-		StringBuffer buf = new StringBuffer( string.length() * times );
-		for ( int i = 0; i < times; i++ ) buf.append( string );
-		return buf.toString();
-	}
-
-	public static String repeat(char character, int times) {
-		char[] buffer = new char[times];
-		Arrays.fill( buffer, character );
-		return new String( buffer );
-	}
-
-
-	public static String replace(String template, String placeholder, String replacement) {
-		return replace( template, placeholder, replacement, false );
-	}
-
-	public static String[] replace(String templates[], String placeholder, String replacement) {
-		String[] result = new String[templates.length];
-		for ( int i =0; i<templates.length; i++ ) {
-			result[i] = replace( templates[i], placeholder, replacement );
-		}
-		return result;
-	}
-
-	public static String replace(String template, String placeholder, String replacement, boolean wholeWords) {
-		if ( template == null ) {
-			return template;
-		}
-		int loc = template.indexOf( placeholder );
-		if ( loc < 0 ) {
-			return template;
-		}
-		else {
-			final boolean actuallyReplace = !wholeWords ||
-					loc + placeholder.length() == template.length() ||
-					!Character.isJavaIdentifierPart( template.charAt( loc + placeholder.length() ) );
-			String actualReplacement = actuallyReplace ? replacement : placeholder;
-			return new StringBuffer( template.substring( 0, loc ) )
-					.append( actualReplacement )
-					.append( replace( template.substring( loc + placeholder.length() ),
-							placeholder,
-							replacement,
-							wholeWords ) ).toString();
-		}
-	}
-
-
-	public static String replaceOnce(String template, String placeholder, String replacement) {
-		if ( template == null ) {
-			return template; // returnign null!
-		}
-        int loc = template.indexOf( placeholder );
-		if ( loc < 0 ) {
-			return template;
-		}
-		else {
-			return new StringBuffer( template.substring( 0, loc ) )
-					.append( replacement )
-					.append( template.substring( loc + placeholder.length() ) )
-					.toString();
-		}
-	}
-
-
-	public static String[] split(String seperators, String list) {
-		return split( seperators, list, false );
-	}
-
-	public static String[] split(String seperators, String list, boolean include) {
-		StringTokenizer tokens = new StringTokenizer( list, seperators, include );
-		String[] result = new String[ tokens.countTokens() ];
-		int i = 0;
-		while ( tokens.hasMoreTokens() ) {
-			result[i++] = tokens.nextToken();
-		}
-		return result;
-	}
-
-	public static String unqualify(String qualifiedName) {
-		int loc = qualifiedName.lastIndexOf(".");
-		return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( qualifiedName.lastIndexOf(".") + 1 );
-	}
-
-	public static String qualifier(String qualifiedName) {
-		int loc = qualifiedName.lastIndexOf(".");
-		return ( loc < 0 ) ? "" : qualifiedName.substring( 0, loc );
-	}
-
-	/**
-	 * Collapses a name.  Mainly intended for use with classnames, where an example might serve best to explain.
-	 * Imagine you have a class named <samp>'org.hibernate.util.StringHelper'</samp>; calling collapse on that
-	 * classname will result in <samp>'o.h.u.StringHelper'<samp>.
-	 *
-	 * @param name The name to collapse.
-	 * @return The collapsed name.
-	 */
-	public static String collapse(String name) {
-		if ( name == null ) {
-			return null;
-		}
-		int breakPoint = name.lastIndexOf( '.' );
-		if ( breakPoint < 0 ) {
-			return name;
-		}
-		return collapseQualifier( name.substring( 0, breakPoint ), true ) + name.substring( breakPoint ); // includes last '.'
-	}
-
-	/**
-	 * Given a qualifier, collapse it.
-	 *
-	 * @param qualifier The qualifier to collapse.
-	 * @param includeDots Should we include the dots in the collapsed form?
-	 *
-	 * @return The collapsed form.
-	 */
-	public static String collapseQualifier(String qualifier, boolean includeDots) {
-		StringTokenizer tokenizer = new StringTokenizer( qualifier, "." );
-		String collapsed = Character.toString( tokenizer.nextToken().charAt( 0 ) );
-		while ( tokenizer.hasMoreTokens() ) {
-			if ( includeDots ) {
-				collapsed += '.';
-			}
-			collapsed += tokenizer.nextToken().charAt( 0 );
-		}
-		return collapsed;
-	}
-
-	/**
-	 * Partially unqualifies a qualified name.  For example, with a base of 'org.hibernate' the name
-	 * 'org.hibernate.util.StringHelper' would become 'util.StringHelper'.
-	 *
-	 * @param name The (potentially) qualified name.
-	 * @param qualifierBase The qualifier base.
-	 *
-	 * @return The name itself, or the partially unqualified form if it begins with the qualifier base.
-	 */
-	public static String partiallyUnqualify(String name, String qualifierBase) {
-		if ( name == null || ! name.startsWith( qualifierBase ) ) {
-			return name;
-		}
-		return name.substring( qualifierBase.length() + 1 ); // +1 to start after the following '.'
-	}
-
-	/**
-	 * Cross between {@link #collapse} and {@link #partiallyUnqualify}.  Functions much like {@link #collapse}
-	 * except that only the qualifierBase is collapsed.  For example, with a base of 'org.hibernate' the name
-	 * 'org.hibernate.util.StringHelper' would become 'o.h.util.StringHelper'.
-	 *
-	 * @param name The (potentially) qualified name.
-	 * @param qualifierBase The qualifier base.
-	 *
-	 * @return The name itself if it does not begin with the qualifierBase, or the properly collapsed form otherwise.
-	 */
-	public static String collapseQualifierBase(String name, String qualifierBase) {
-		if ( name == null || ! name.startsWith( qualifierBase ) ) {
-			return collapse( name );
-		}
-		return collapseQualifier( qualifierBase, true ) + name.substring( qualifierBase.length() );
-	}
-
-	public static String[] suffix(String[] columns, String suffix) {
-		if ( suffix == null ) return columns;
-		String[] qualified = new String[columns.length];
-		for ( int i = 0; i < columns.length; i++ ) {
-			qualified[i] = suffix( columns[i], suffix );
-		}
-		return qualified;
-	}
-
-	private static String suffix(String name, String suffix) {
-		return ( suffix == null ) ? name : name + suffix;
-	}
-
-	public static String root(String qualifiedName) {
-		int loc = qualifiedName.indexOf( "." );
-		return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( 0, loc );
-	}
-
-	public static String unroot(String qualifiedName) {
-		int loc = qualifiedName.indexOf( "." );
-		return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( loc+1, qualifiedName.length() );
-	}
-
-	public static boolean booleanValue(String tfString) {
-		String trimmed = tfString.trim().toLowerCase();
-		return trimmed.equals( "true" ) || trimmed.equals( "t" );
-	}
-
-	public static String toString(Object[] array) {
-		int len = array.length;
-		if ( len == 0 ) return "";
-		StringBuffer buf = new StringBuffer( len * 12 );
-		for ( int i = 0; i < len - 1; i++ ) {
-			buf.append( array[i] ).append(", ");
-		}
-		return buf.append( array[len - 1] ).toString();
-	}
-
-	public static String[] multiply(String string, Iterator placeholders, Iterator replacements) {
-		String[] result = new String[]{string};
-		while ( placeholders.hasNext() ) {
-			result = multiply( result, ( String ) placeholders.next(), ( String[] ) replacements.next() );
-		}
-		return result;
-	}
-
-	private static String[] multiply(String[] strings, String placeholder, String[] replacements) {
-		String[] results = new String[replacements.length * strings.length];
-		int n = 0;
-		for ( int i = 0; i < replacements.length; i++ ) {
-			for ( int j = 0; j < strings.length; j++ ) {
-				results[n++] = replaceOnce( strings[j], placeholder, replacements[i] );
-			}
-		}
-		return results;
-	}
-
-	public static int countUnquoted(String string, char character) {
-		if ( '\'' == character ) {
-			throw new IllegalArgumentException( "Unquoted count of quotes is invalid" );
-		}
-		if (string == null)
-			return 0;
-		// Impl note: takes advantage of the fact that an escpaed single quote
-		// embedded within a quote-block can really be handled as two seperate
-		// quote-blocks for the purposes of this method...
-		int count = 0;
-		int stringLength = string.length();
-		boolean inQuote = false;
-		for ( int indx = 0; indx < stringLength; indx++ ) {
-			char c = string.charAt( indx );
-			if ( inQuote ) {
-				if ( '\'' == c ) {
-					inQuote = false;
-				}
-			}
-			else if ( '\'' == c ) {
-				inQuote = true;
-			}
-			else if ( c == character ) {
-				count++;
-			}
-		}
-		return count;
-	}
-
-	public static boolean isNotEmpty(String string) {
-		return string != null && string.length() > 0;
-	}
-
-	public static boolean isEmpty(String string) {
-		return string == null || string.length() == 0;
-	}
-
-	public static String qualify(String prefix, String name) {
-		if ( name == null || prefix == null ) {
-			throw new NullPointerException();
-		}
-		return new StringBuffer( prefix.length() + name.length() + 1 )
-				.append(prefix)
-				.append('.')
-				.append(name)
-				.toString();
-	}
-
-	public static String[] qualify(String prefix, String[] names) {
-		if ( prefix == null ) return names;
-		int len = names.length;
-		String[] qualified = new String[len];
-		for ( int i = 0; i < len; i++ ) {
-			qualified[i] = qualify( prefix, names[i] );
-		}
-		return qualified;
-	}
-
-	public static int firstIndexOfChar(String sqlString, String string, int startindex) {
-		int matchAt = -1;
-		for ( int i = 0; i < string.length(); i++ ) {
-			int curMatch = sqlString.indexOf( string.charAt( i ), startindex );
-			if ( curMatch >= 0 ) {
-				if ( matchAt == -1 ) { // first time we find match!
-					matchAt = curMatch;
-				}
-				else {
-					matchAt = Math.min( matchAt, curMatch );
-				}
-			}
-		}
-		return matchAt;
-	}
-
-	public static String truncate(String string, int length) {
-		if ( string.length() <= length ) {
-			return string;
-		}
-		else {
-			return string.substring( 0, length );
-		}
-	}
-
-	public static String generateAlias(String description) {
-		return generateAliasRoot(description) + '_';
-	}
-
-	/**
-	 * Generate a nice alias for the given class name or collection role name and unique integer. Subclasses of
-	 * Loader do <em>not</em> have to use aliases of this form.
-	 *
-	 * @param description The base name (usually an entity-name or collection-role)
-	 * @param unique A uniquing value
-	 *
-	 * @return an alias of the form <samp>foo1_</samp>
-	 */
-	public static String generateAlias(String description, int unique) {
-		return generateAliasRoot(description) +
-			Integer.toString(unique) +
-			'_';
-	}
-
-	/**
-	 * Generates a root alias by truncating the "root name" defined by
-	 * the incoming decription and removing/modifying any non-valid
-	 * alias characters.
-	 *
-	 * @param description The root name from which to generate a root alias.
-	 * @return The generated root alias.
-	 */
-	private static String generateAliasRoot(String description) {
-		String result = truncate( unqualifyEntityName(description), ALIAS_TRUNCATE_LENGTH )
-				.toLowerCase()
-		        .replace( '/', '_' ) // entityNames may now include slashes for the representations
-				.replace( '$', '_' ); //classname may be an inner class
-		result = cleanAlias( result );
-		if ( Character.isDigit( result.charAt(result.length()-1) ) ) {
-			return result + "x"; //ick!
-		}
-		else {
-			return result;
-		}
-	}
-
-	/**
-	 * Clean the generated alias by removing any non-alpha characters from the
-	 * beginning.
-	 *
-	 * @param alias The generated alias to be cleaned.
-	 * @return The cleaned alias, stripped of any leading non-alpha characters.
-	 */
-	private static String cleanAlias(String alias) {
-		char[] chars = alias.toCharArray();
-		// short cut check...
-		if ( !Character.isLetter( chars[0] ) ) {
-			for ( int i = 1; i < chars.length; i++ ) {
-				// as soon as we encounter our first letter, return the substring
-				// from that position
-				if ( Character.isLetter( chars[i] ) ) {
-					return alias.substring( i );
-				}
-			}
-		}
-		return alias;
-	}
-
-	public static String unqualifyEntityName(String entityName) {
-		String result = unqualify(entityName);
-		int slashPos = result.indexOf( '/' );
-		if ( slashPos > 0 ) {
-			result = result.substring( 0, slashPos - 1 );
-		}
-		return result;
-	}
-
-	public static String toUpperCase(String str) {
-		return str==null ? null : str.toUpperCase();
-	}
-
-	public static String toLowerCase(String str) {
-		return str==null ? null : str.toLowerCase();
-	}
-
-	public static String moveAndToBeginning(String filter) {
-		if ( filter.trim().length()>0 ){
-			filter += " and ";
-			if ( filter.startsWith(" and ") ) filter = filter.substring(4);
-		}
-		return filter;
-	}
-
-	/**
-	 * Determine if the given string is quoted (wrapped by '`' characters at beginning and end).
-	 *
-	 * @param name The name to check.
-	 * @return True if the given string starts and ends with '`'; false otherwise.
-	 */
-	public static boolean isQuoted(String name) {
-		return name != null && name.length() != 0 && name.charAt( 0 ) == '`' && name.charAt( name.length() - 1 ) == '`';
-	}
-
-	/**
-	 * Return a representation of the given name ensuring quoting (wrapped with '`' characters).  If already wrapped
-	 * return name.
-	 *
-	 * @param name The name to quote.
-	 * @return The quoted version.
-	 */
-	public static String quote(String name) {
-		if ( name == null || name.length() == 0 || isQuoted( name ) ) {
-			return name;
-		}
-		else {
-			return new StringBuffer( name.length() + 2 ).append('`').append( name ).append( '`' ).toString();
-		}
-	}
-
-	/**
-	 * Return the unquoted version of name (stripping the start and end '`' characters if present).
-	 *
-	 * @param name The name to be unquoted.
-	 * @return The unquoted version.
-	 */
-	public static String unquote(String name) {
-		if ( isQuoted( name ) ) {
-			return name.substring( 1, name.length() - 1 );
-		}
-		else {
-			return name;
-		}
-	}
-}
\ No newline at end of file
diff --git a/src/test/java/org/hibernate/annotations/common/test/annotationfactory/AnnotationFactoryTest.java b/src/test/java/org/hibernate/annotations/common/test/annotationfactory/AnnotationFactoryTest.java
index dbe9da6..f4f40f0 100644
--- a/src/test/java/org/hibernate/annotations/common/test/annotationfactory/AnnotationFactoryTest.java
+++ b/src/test/java/org/hibernate/annotations/common/test/annotationfactory/AnnotationFactoryTest.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.annotationfactory;
 
 import junit.framework.TestCase;
diff --git a/src/test/java/org/hibernate/annotations/common/test/annotationfactory/AnnotationProxyTest.java b/src/test/java/org/hibernate/annotations/common/test/annotationfactory/AnnotationProxyTest.java
index 9ce4c44..70691a4 100644
--- a/src/test/java/org/hibernate/annotations/common/test/annotationfactory/AnnotationProxyTest.java
+++ b/src/test/java/org/hibernate/annotations/common/test/annotationfactory/AnnotationProxyTest.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.annotationfactory;
 
 import java.lang.reflect.Method;
diff --git a/src/test/java/org/hibernate/annotations/common/test/annotationfactory/TestAnnotation.java b/src/test/java/org/hibernate/annotations/common/test/annotationfactory/TestAnnotation.java
index 6930f11..f6b9f6d 100644
--- a/src/test/java/org/hibernate/annotations/common/test/annotationfactory/TestAnnotation.java
+++ b/src/test/java/org/hibernate/annotations/common/test/annotationfactory/TestAnnotation.java
@@ -1,3 +1,10 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
+
 /**
  * 
  */
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/Foo.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/Foo.java
index 614e885..020e348 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/Foo.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/Foo.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java;
 
 import java.util.List;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/FooFather.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/FooFather.java
index 8768ddf..3a6266b 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/FooFather.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/FooFather.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java;
 
 import java.util.List;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaReflectionManagerTest.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaReflectionManagerTest.java
index 3f09d40..5b8ddce 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaReflectionManagerTest.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaReflectionManagerTest.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java;
 
 import junit.framework.TestCase;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXClassTest.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXClassTest.java
index 1a94713..d7a6f1e 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXClassTest.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXClassTest.java
@@ -1,6 +1,14 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java;
 
 import java.io.Serializable;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.List;
 
 import org.hibernate.annotations.common.reflection.ReflectionManager;
@@ -82,6 +90,19 @@ public class JavaXClassTest extends XAnnotatedElementTestCase {
 		assertTrue( factory.toXClass( Sex.class ).isEnum() );
 	}
 
+	public void testParameterizedType() {
+		Type type = factory.toType(
+			fatherAsSeenFromSon.getDeclaredProperties( "property" )
+				.stream()
+				.filter( p -> p.getName().equals( "genericCollectionProperty" ) )
+				.findFirst()
+				.get()
+				.getType()
+		);
+		assertTrue( type instanceof ParameterizedType );
+		assertEquals( String.class, ((ParameterizedType) type).getActualTypeArguments()[0] );
+	}
+
 	@Override
 	protected XAnnotatedElement getConcreteInstance() {
 		return factory.toXClass( Dad.class );
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXPropertyTest.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXPropertyTest.java
index 4e4946d..4cbf372 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXPropertyTest.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXPropertyTest.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java;
 
 import java.util.LinkedList;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/Sex.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/Sex.java
index dfc12b7..1015522 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/Sex.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/Sex.java
@@ -1,3 +1,10 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
+
 //$Id: $
 package org.hibernate.annotations.common.test.reflection.java;
 
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/TestAnnotation.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/TestAnnotation.java
index 96cbfd9..16c55c1 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/TestAnnotation.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/TestAnnotation.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java;
 
 import static java.lang.annotation.ElementType.*;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/XAnnotatedElementTestCase.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/XAnnotatedElementTestCase.java
index c722d3d..7ad8951 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/XAnnotatedElementTestCase.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/XAnnotatedElementTestCase.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java;
 
 import junit.framework.TestCase;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/ApproximatingTypeEnvironmentTest.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/ApproximatingTypeEnvironmentTest.java
index 843b564..10fd193 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/ApproximatingTypeEnvironmentTest.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/ApproximatingTypeEnvironmentTest.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 import java.lang.reflect.ParameterizedType;
@@ -11,12 +17,11 @@ import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironment
 
 public class ApproximatingTypeEnvironmentTest extends TestCase {
 
-	TypeEnvironmentFactory teFactory = new TypeEnvironmentFactory();
-	TypeEnvironment unboundContext = teFactory.getEnvironment( BigBlob.class );
-	TypeEnvironment approximatingUnboundContext = teFactory.toApproximatingEnvironment( unboundContext );
+	TypeEnvironment unboundContext = TypeEnvironmentFactory.getEnvironment( BigBlob.class );
+	TypeEnvironment approximatingUnboundContext = TypeEnvironmentFactory.toApproximatingEnvironment( unboundContext );
 
-	TypeEnvironment boundContext = teFactory.getEnvironment( SonOfBlob.class );
-	TypeEnvironment approximatingBoundContext = teFactory.toApproximatingEnvironment( boundContext );
+	TypeEnvironment boundContext = TypeEnvironmentFactory.getEnvironment( SonOfBlob.class );
+	TypeEnvironment approximatingBoundContext = TypeEnvironmentFactory.toApproximatingEnvironment( boundContext );
 
 	public void testDoesNothingOnClasses() throws SecurityException {
 		assertEquals( String[].class, approximatingUnboundContext.bind( String[].class ) );
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/BigBlob.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/BigBlob.java
index ca533df..5a76d9d 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/BigBlob.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/BigBlob.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 import java.util.Collection;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Dad.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Dad.java
index 39d6fa1..c5e2051 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Dad.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Dad.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 import java.util.List;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Grandpa.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Grandpa.java
index 1864581..ec4b4db 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Grandpa.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Grandpa.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 import java.io.Serializable;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Language.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Language.java
index e9834ac..dee10b0 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Language.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Language.java
@@ -1,4 +1,11 @@
-//$Id: Language.java 11282 2007-03-14 22:05:59Z epbernard $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
+
+//$Id$
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 /**
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Neighbour.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Neighbour.java
index 096fc1b..ef757e3 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Neighbour.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Neighbour.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 import java.util.Set;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Son.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Son.java
index 7fecf00..94a1d23 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Son.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/Son.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 /**
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/SonOfBlob.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/SonOfBlob.java
index cbbb3d7..66b397b 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/SonOfBlob.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/SonOfBlob.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 import java.util.List;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TestAnnotation.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TestAnnotation.java
index f3de93e..dc66c6b 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TestAnnotation.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TestAnnotation.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 import static java.lang.annotation.ElementType.*;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TypeEnvironmentFactoryTest.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TypeEnvironmentFactoryTest.java
index 8991dfc..3349474 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TypeEnvironmentFactoryTest.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TypeEnvironmentFactoryTest.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 import java.lang.reflect.ParameterizedType;
@@ -16,33 +22,31 @@ import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironment
 public class TypeEnvironmentFactoryTest extends TestCase {
 
 	public void testBindsGenericsToSuperclassEnvironment() throws SecurityException, NoSuchMethodException {
-		TypeEnvironmentFactory env = new TypeEnvironmentFactory();
-		Type type = Grandpa.class.getMethod( "returnsGeneric", new Class[0] ).getGenericReturnType();
+		Type type = Grandpa.class.getMethod( "returnsGeneric" ).getGenericReturnType();
 
-		Type asSeenFromGrandpa = env.getEnvironment( Grandpa.class ).bind( type );
+		Type asSeenFromGrandpa = TypeEnvironmentFactory.getEnvironment( Grandpa.class ).bind( type );
 		assertTrue( asSeenFromGrandpa instanceof TypeVariable );
 		assertEquals( "T", asSeenFromGrandpa.toString() );
 
-		Type asSeenFromDad = env.getEnvironment( Dad.class ).bind( type );
+		Type asSeenFromDad = TypeEnvironmentFactory.getEnvironment( Dad.class ).bind( type );
 		assertTrue( asSeenFromDad instanceof ParameterizedType );
 		assertEquals( "java.util.List<T>", asSeenFromDad.toString() );
 
-		ParameterizedType asSeenFromSon = (ParameterizedType) env.getEnvironment( Son.class ).bind( type );
+		ParameterizedType asSeenFromSon = (ParameterizedType) TypeEnvironmentFactory.getEnvironment( Son.class ).bind( type );
 		assertType_isCollectionOfClass_withElementsOfClass( asSeenFromSon, List.class, String.class );
 	}
 
+	@SuppressWarnings("unchecked")
 	public void testBindsGenericsToOwnerEnvironment() throws SecurityException, NoSuchMethodException {
-		TypeEnvironmentFactory env = new TypeEnvironmentFactory();
-
-		Type friendType = Dad.class.getMethod( "getFriend", new Class[0] ).getGenericReturnType();
-		ParameterizedType friendTypeAsSeenFromDad = (ParameterizedType) env.getEnvironment( Dad.class ).bind(
+		Type friendType = Dad.class.getMethod( "getFriend" ).getGenericReturnType();
+		ParameterizedType friendTypeAsSeenFromDad = (ParameterizedType) TypeEnvironmentFactory.getEnvironment( Dad.class ).bind(
 				friendType
 		);
 
 		Class friendClass = (Class) friendTypeAsSeenFromDad.getRawType();
-		Type returnType = friendClass.getMethod( "embeddedProperty", new Class[0] ).getGenericReturnType();
+		Type returnType = friendClass.getMethod( "embeddedProperty" ).getGenericReturnType();
 
-		ParameterizedType boundType = (ParameterizedType) env.getEnvironment( friendTypeAsSeenFromDad ).bind(
+		ParameterizedType boundType = (ParameterizedType) TypeEnvironmentFactory.getEnvironment( friendTypeAsSeenFromDad ).bind(
 				returnType
 		);
 		assertType_isCollectionOfClass_withElementsOfClass( boundType, Set.class, Integer.class );
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TypeUtilsTest.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TypeUtilsTest.java
index 7d6c9e9..f7d0237 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TypeUtilsTest.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/TypeUtilsTest.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics;
 
 import java.lang.reflect.Type;
@@ -10,9 +16,8 @@ import org.hibernate.annotations.common.reflection.java.generics.TypeUtils;
 
 public class TypeUtilsTest extends TestCase {
 
-	TypeEnvironmentFactory env = new TypeEnvironmentFactory();
-	TypeEnvironment dadContext = env.getEnvironment( Dad.class );
-	TypeEnvironment sonContext = env.getEnvironment( Son.class );
+	TypeEnvironment dadContext = TypeEnvironmentFactory.getEnvironment( Dad.class );
+	TypeEnvironment sonContext = TypeEnvironmentFactory.getEnvironment( Son.class );
 
 	public void testAClassIsAlwaysFullyResolved() throws Exception {
 		assertTrue( TypeUtils.isResolved( Dad.class ) );
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/ANN612IssueTest.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/ANN612IssueTest.java
index 89c6d57..6179d94 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/ANN612IssueTest.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/ANN612IssueTest.java
@@ -1,3 +1,10 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
+
 //$Id: $
 package org.hibernate.annotations.common.test.reflection.java.generics.deep;
 
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DeepGenericsContainment.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DeepGenericsContainment.java
index 38e0363..8bcccc8 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DeepGenericsContainment.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DeepGenericsContainment.java
@@ -1,3 +1,10 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
+
 //$Id: $
 package org.hibernate.annotations.common.test.reflection.java.generics.deep;
 
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DeepGenericsInheritance.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DeepGenericsInheritance.java
index 5f63ddd..6562b8b 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DeepGenericsInheritance.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DeepGenericsInheritance.java
@@ -1,3 +1,10 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
+
 //$Id: $
 package org.hibernate.annotations.common.test.reflection.java.generics.deep;
 
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Dummy.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Dummy.java
index 2dba445..d6bcd84 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Dummy.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Dummy.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics.deep;
 
 public class Dummy {
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DummySubclass.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DummySubclass.java
index 2b2604a..c16b428 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DummySubclass.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/DummySubclass.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics.deep;
 
 import org.hibernate.annotations.common.test.reflection.java.generics.deep.Dummy;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/GenericSuperclass1.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/GenericSuperclass1.java
index 051b75c..24266c3 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/GenericSuperclass1.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/GenericSuperclass1.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics.deep;
 
 import org.hibernate.annotations.common.test.reflection.java.generics.deep.Dummy;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/GenericSuperclass2.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/GenericSuperclass2.java
index 517096e..77067dc 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/GenericSuperclass2.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/GenericSuperclass2.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics.deep;
 
 import org.hibernate.annotations.common.test.reflection.java.generics.deep.Dummy;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Subclass1.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Subclass1.java
index c6f8300..e72c2fa 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Subclass1.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Subclass1.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics.deep;
 
 import org.hibernate.annotations.common.test.reflection.java.generics.deep.DummySubclass;
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Subclass2.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Subclass2.java
index c331ea8..aa76a46 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Subclass2.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/generics/deep/Subclass2.java
@@ -1,3 +1,9 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
+ * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ */
 package org.hibernate.annotations.common.test.reflection.java.generics.deep;
 
 import org.hibernate.annotations.common.test.reflection.java.generics.deep.DummySubclass;
diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties
new file mode 100644
index 0000000..2a7ff31
--- /dev/null
+++ b/src/test/resources/log4j.properties
@@ -0,0 +1,8 @@
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+log4j.rootLogger=info, stdout
+

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/share/java/hibernate-commons-annotations.jar
-rw-r--r--  root/root   /usr/share/maven-repo/org/hibernate/hibernate-commons-annotations/3.2.0.Final/hibernate-commons-annotations-3.2.0.Final.pom
-rw-r--r--  root/root   /usr/share/maven-repo/org/hibernate/hibernate-commons-annotations/debian/hibernate-commons-annotations-debian.pom
lrwxrwxrwx  root/root   /usr/share/java/hibernate-commons-annotations-3.2.0.Final.jar -> hibernate-commons-annotations.jar
lrwxrwxrwx  root/root   /usr/share/maven-repo/org/hibernate/hibernate-commons-annotations/3.2.0.Final/hibernate-commons-annotations-3.2.0.Final.jar -> ../../../../../java/hibernate-commons-annotations.jar
lrwxrwxrwx  root/root   /usr/share/maven-repo/org/hibernate/hibernate-commons-annotations/debian/hibernate-commons-annotations-debian.jar -> ../../../../../java/hibernate-commons-annotations.jar

No differences were encountered in the control files

More details

Full run details