[qdox2] 01/04: New upstream version 2.0~M6

Markus Koschany apo at moszumanska.debian.org
Fri Jul 28 12:03:44 UTC 2017


This is an automated email from the git hooks/post-receive script.

apo pushed a commit to branch master
in repository qdox2.

commit efc0b4b23c1d02d0e41566cb4dab7da95a92bd2a
Author: Markus Koschany <apo at debian.org>
Date:   Fri Jul 28 13:55:29 2017 +0200

    New upstream version 2.0~M6
---
 .gitignore                                         |   5 +
 .travis.yml                                        |   4 +
 README.md                                          | 572 +++++++++++++++++++++
 README.txt                                         |  26 -
 pom.xml                                            | 117 +----
 src/grammar/commentlexer.flex                      |   5 +
 src/grammar/lexer.flex                             |  87 +++-
 src/grammar/parser.y                               | 218 ++++++--
 src/it/lambda-examples/verify.groovy               |   8 +-
 .../com/thoughtworks/qdox/JavaProjectBuilder.java  |  17 +-
 .../com/thoughtworks/qdox/builder/Builder.java     |  12 +
 .../thoughtworks/qdox/builder/TypeAssembler.java   |  25 +-
 .../impl/DefaultJavaAnnotationAssembler.java       |  34 +-
 .../qdox/builder/impl/EvaluatingVisitor.java       |  62 ++-
 .../qdox/builder/impl/ModelBuilder.java            | 186 ++++++-
 .../qdox/library/AbstractClassLibrary.java         |  30 +-
 .../thoughtworks/qdox/library/ClassLibrary.java    |  11 +-
 .../qdox/library/ClassLibraryBuilder.java          |  43 +-
 .../qdox/library/ClassLoaderLibrary.java           |  13 +-
 .../qdox/library/ClassNameLibrary.java             |  14 +-
 .../qdox/library/JavaClassContext.java             |   2 +-
 .../qdox/library/OrderedClassLibraryBuilder.java   |  20 +-
 .../qdox/library/SortedClassLibraryBuilder.java    |   5 +
 .../qdox/library/SourceFolderLibrary.java          |  57 +-
 .../thoughtworks/qdox/library/SourceLibrary.java   |  64 ++-
 .../thoughtworks/qdox/model/DocletTagFactory.java  |  13 +
 .../thoughtworks/qdox/model/JavaAnnotation.java    |   2 +-
 .../com/thoughtworks/qdox/model/JavaClass.java     | 158 ++----
 .../thoughtworks/qdox/model/JavaConstructor.java   |  63 +--
 .../thoughtworks/qdox/model/JavaExecutable.java    |  70 +++
 .../com/thoughtworks/qdox/model/JavaField.java     |   6 -
 .../qdox/model/JavaGenericDeclaration.java         |   1 +
 .../com/thoughtworks/qdox/model/JavaMethod.java    |  61 +--
 .../com/thoughtworks/qdox/model/JavaModel.java     |   7 -
 .../thoughtworks/qdox/model/JavaModelUtils.java    |   8 +-
 .../com/thoughtworks/qdox/model/JavaModule.java    |  12 +
 .../qdox/model/JavaModuleDescriptor.java           | 104 ++++
 .../com/thoughtworks/qdox/model/JavaParameter.java |   5 +-
 .../com/thoughtworks/qdox/model/JavaSource.java    |  22 +-
 .../java/com/thoughtworks/qdox/model/JavaType.java | 108 ++--
 .../qdox/model/ParameterDeclarator.java            |  13 -
 .../thoughtworks/qdox/model/expression/Add.java    |   3 +
 .../thoughtworks/qdox/model/expression/And.java    |   3 +
 .../qdox/model/expression/AnnotationValueList.java |  12 +-
 .../thoughtworks/qdox/model/expression/Cast.java   |   3 +
 .../qdox/model/expression/Constant.java            |  15 +-
 .../thoughtworks/qdox/model/expression/Divide.java |   3 +
 .../thoughtworks/qdox/model/expression/Equals.java |   3 +
 .../qdox/model/expression/ExclusiveOr.java         |   3 +
 .../qdox/model/expression/Expression.java          |   2 +-
 .../qdox/model/expression/FieldRef.java            |  56 +-
 .../qdox/model/expression/GreaterEquals.java       |   3 +
 .../qdox/model/expression/GreaterThan.java         |   3 +
 .../qdox/model/expression/LessEquals.java          |   3 +
 .../qdox/model/expression/LessThan.java            |   3 +
 .../qdox/model/expression/LogicalAnd.java          |   3 +
 .../qdox/model/expression/LogicalNot.java          |   3 +
 .../qdox/model/expression/LogicalOr.java           |   3 +
 .../qdox/model/expression/MethodInvocation.java    |   2 +
 .../qdox/model/expression/MinusSign.java           |   3 +
 .../qdox/model/expression/Multiply.java            |   3 +
 .../thoughtworks/qdox/model/expression/Not.java    |   3 +
 .../qdox/model/expression/NotEquals.java           |   3 +
 .../com/thoughtworks/qdox/model/expression/Or.java |   3 +
 .../qdox/model/expression/ParenExpression.java     |   3 +
 .../qdox/model/expression/PlusSign.java            |   3 +
 .../thoughtworks/qdox/model/expression/Query.java  |   3 +
 .../qdox/model/expression/Remainder.java           |   3 +
 .../qdox/model/expression/ShiftLeft.java           |   3 +
 .../qdox/model/expression/ShiftRight.java          |   3 +
 .../qdox/model/expression/Subtract.java            |   3 +
 .../qdox/model/expression/TypeRef.java             |   3 +
 .../qdox/model/expression/UnsignedShiftRight.java  |   3 +
 .../qdox/model/impl/AbstractBaseJavaEntity.java    |  14 +-
 .../qdox/model/impl/AbstractJavaEntity.java        |  13 +-
 .../qdox/model/impl/AbstractJavaModel.java         |  13 +-
 .../qdox/model/impl/DefaultDocletTagFactory.java   |   2 +
 .../qdox/model/impl/DefaultJavaAnnotation.java     |  34 +-
 .../qdox/model/impl/DefaultJavaClass.java          | 146 ++----
 .../qdox/model/impl/DefaultJavaConstructor.java    |   8 +-
 ...tBaseMethod.java => DefaultJavaExecutable.java} |  24 +-
 .../qdox/model/impl/DefaultJavaField.java          |  36 +-
 .../qdox/model/impl/DefaultJavaInitializer.java    |   3 +
 .../qdox/model/impl/DefaultJavaMethod.java         |  26 +-
 .../qdox/model/impl/DefaultJavaModule.java         |  43 ++
 .../model/impl/DefaultJavaModuleDescriptor.java    | 311 +++++++++++
 .../qdox/model/impl/DefaultJavaParameter.java      |  31 +-
 .../model/impl/DefaultJavaParameterizedType.java   |  54 +-
 .../qdox/model/impl/DefaultJavaSource.java         | 216 +-------
 .../qdox/model/impl/DefaultJavaType.java           | 261 ++++------
 .../qdox/model/impl/DefaultJavaTypeVariable.java   |  48 +-
 .../qdox/model/impl/DefaultJavaWildcardType.java   |   9 +-
 .../qdox/model/impl/JavaClassParent.java           |  48 --
 .../qdox/model/impl/JavaMethodDelegate.java        |  81 ++-
 .../thoughtworks/qdox/model/util/TagParser.java    |  14 +-
 .../qdox/parser/expression/AddDef.java             |   1 +
 .../qdox/parser/expression/AndDef.java             |   1 +
 .../qdox/parser/expression/AssignmentDef.java      |   1 +
 .../qdox/parser/expression/CastDef.java            |   1 +
 .../qdox/parser/expression/ConstantDef.java        |   1 +
 .../qdox/parser/expression/CreatorDef.java         |   1 +
 .../qdox/parser/expression/DivideDef.java          |   1 +
 .../qdox/parser/expression/ElemValueListDef.java   |   1 +
 .../parser/expression/ElemValueTransformer.java    |   3 +
 .../qdox/parser/expression/EqualsDef.java          |   1 +
 .../qdox/parser/expression/ExclusiveOrDef.java     |   1 +
 .../qdox/parser/expression/FieldRefDef.java        |   1 +
 .../qdox/parser/expression/GreaterEqualsDef.java   |   1 +
 .../qdox/parser/expression/GreaterThanDef.java     |   1 +
 .../qdox/parser/expression/LessEqualsDef.java      |   1 +
 .../qdox/parser/expression/LessThanDef.java        |   1 +
 .../qdox/parser/expression/LogicalAndDef.java      |   1 +
 .../qdox/parser/expression/LogicalNotDef.java      |   1 +
 .../qdox/parser/expression/LogicalOrDef.java       |   1 +
 .../parser/expression/MethodInvocationDef.java     |   1 +
 .../qdox/parser/expression/MethodReferenceDef.java |  10 +
 .../qdox/parser/expression/MinusSignDef.java       |   1 +
 .../qdox/parser/expression/MultiplyDef.java        |   1 +
 .../qdox/parser/expression/NotDef.java             |   1 +
 .../qdox/parser/expression/NotEqualsDef.java       |   1 +
 .../thoughtworks/qdox/parser/expression/OrDef.java |   1 +
 .../qdox/parser/expression/ParenExpressionDef.java |   1 +
 .../qdox/parser/expression/PlusSignDef.java        |   1 +
 .../qdox/parser/expression/PostDecrementDef.java   |   1 +
 .../qdox/parser/expression/PostIncrementDef.java   |   1 +
 .../qdox/parser/expression/PreDecrementDef.java    |   1 +
 .../qdox/parser/expression/PreIncrementDef.java    |   1 +
 .../qdox/parser/expression/QueryDef.java           |   1 +
 .../qdox/parser/expression/RemainderDef.java       |   1 +
 .../qdox/parser/expression/ShiftLeftDef.java       |   1 +
 .../qdox/parser/expression/ShiftRightDef.java      |   1 +
 .../qdox/parser/expression/SubtractDef.java        |   1 +
 .../qdox/parser/expression/TypeRefDef.java         |   1 +
 .../parser/expression/UnsignedShiftRightDef.java   |   1 +
 .../qdox/parser/impl/BinaryClassParser.java        |  31 +-
 .../thoughtworks/qdox/parser/structs/AnnoDef.java  |   1 +
 .../qdox/parser/structs/ModuleDef.java             | 149 ++++++
 .../com/thoughtworks/qdox/type/TypeResolver.java   | 287 +++++++++++
 .../com/thoughtworks/qdox/writer/ModelWriter.java  |  64 +++
 .../qdox/writer/impl/DefaultModelWriter.java       | 151 +++++-
 .../qdox/writer/impl/IndentBuffer.java             |   1 +
 src/test/java/X.java                               |  17 +
 .../com/thoughtworks/qdox/ClassResolutionTest.java |  11 +-
 .../java/com/thoughtworks/qdox/EnumsModelTest.java |  49 +-
 .../java/com/thoughtworks/qdox/GenericsTest.java   |   2 +-
 .../thoughtworks/qdox/JavaProjectBuilderTest.java  | 141 ++++-
 .../qdox/builder/impl/EvaluatingVisitorTest.java   |  27 +-
 .../qdox/builder/impl/ModelBuilderTest.java        |   5 +-
 .../qdox/library/AbstractClassLibraryTest.java     |   8 +
 .../qdox/library/ClassLibraryBuilderTest.java      |   5 +-
 .../qdox/library/ClassLoaderLibraryTest.java       |   4 +
 .../qdox/library/SourceFolderLibraryTest.java      | 112 ++++
 .../qdox/library/SourceLibraryTest.java            |   5 +
 .../com/thoughtworks/qdox/model/JavaClassTest.java |  61 +--
 .../qdox/model/JavaConstructorTest.java            |   8 +-
 .../com/thoughtworks/qdox/model/JavaFieldTest.java |  24 -
 .../thoughtworks/qdox/model/JavaMethodTest.java    |  24 +-
 .../thoughtworks/qdox/model/JavaParameterTest.java |  43 +-
 .../thoughtworks/qdox/model/JavaSourceTest.java    | 101 ----
 .../com/thoughtworks/qdox/model/JavaTypeTest.java  |  21 +-
 .../qdox/model/impl/DefaultJavaClassIT.java        |  10 +-
 .../qdox/model/impl/DefaultJavaClassTest.java      |   2 +-
 .../model/impl/DefaultJavaConstructorTest.java     |   6 +-
 .../qdox/model/impl/DefaultJavaFieldTest.java      |   6 +-
 .../qdox/model/impl/DefaultJavaMethodTest.java     |   4 +-
 .../qdox/model/impl/DefaultJavaParameterTest.java  |  14 +-
 .../impl/DefaultJavaParameterizedTypeTest.java     | 154 ++++++
 .../qdox/model/impl/DefaultTypeTest.java           |  29 +-
 .../com/thoughtworks/qdox/parser/LexerTest.java    | 205 ++++++++
 .../com/thoughtworks/qdox/parser/ParserTest.java   | 389 ++++++++++----
 .../parser/impl/DefaultJavaCommentLexerTest.java   |  16 +
 .../thoughtworks/qdox/traversal/TraversalTest.java |   4 +-
 .../thoughtworks/qdox/type/TypeResolverTest.java   | 167 ++++++
 .../qdox/writer/impl/DefaultModelWriterTest.java   | 150 ++++++
 .../thoughtworks/qdox/testdata/module-info.java    |   4 +
 .../resources/jigsaw/example1/module-info.java     |  16 +
 .../resources/jigsaw/example2/module-info.java     |  13 +
 177 files changed, 4578 insertions(+), 1906 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a39f201
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+/target/
+/.project
+/target
+/.classpath
+/.settings
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..4fbaf4a
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,4 @@
+language: java
+jdk:
+  - oraclejdk8
+script: mvn clean verify
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4916a6c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,572 @@
+# QDox
+
+### Status
+
+[![Build Status](https://travis-ci.org/paul-hammant/qdox.png)](https://travis-ci.org/paul-hammant/qdox)
+
+QDox is a high speed, small footprint parser for fully extracting class/interface/method definitions (including annotations, parameters, param names). It is designed to be used by active code generators or documentation tools.
+
+Not so relevant any more, but it also also processes JavaDoc @tags
+
+# Migration from Codehaus
+
+This project used to be on Codehaus, in Subversion. The trunk of that has been git-svn-cloned to here. Maven repos have the sources jars for released versions of Qdox.  The [old issues from codehaus are hosted statically on a GH-pages repo](http://paul-hammant.github.io/Old_Qdox_Issues/)
+
+# Download
+
+Maven's central repo [holds versions of QDox](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.thoughtworks.qdox%22%20AND%20a%3A%22qdox%22)
+
+# In A Nutshell
+
+A custom built parser has been built using JFlex and BYacc/J. These have been chosen because of their proven performance and they require no external libraries at runtime.
+
+The parser skims the source files only looking for things of interest such as class/interface definitions, import statements, JavaDoc and member declarations. The parser ignores things such as actual method implementations to avoid overhead (while in method blocks, curly brace counting suffices).
+
+The end result of the parser is a very simple document model containing enough information to be useful.
+
+# Frequently Asked Questions
+
+## General
+
+### What's the object type of an interface?
+
+The JavaClass method is used to represent both classes and interfaces. The isInterface() method allows you to distinguish between the two.
+
+When using a class, the getSuperClass() return which class is extended. If this has not been defined in the input source code, java.lang.Object is returned. When using an interface, this method ALWAYS returns null.
+
+When using a class, the getImplements() returns an array of the interfaces implemented by the class. If none are implemented, an empty array is returned. When using an interface, this returns an array of interfaces the current interface EXTENDS.
+
+## Can I have full control over the classloader?
+
+I some cases QDox is used to generate classes for another project with it's own dependencies. This could result in class-collision. By default the JavadocBuilder will contain the classloader(s) of the current project, but by defining your own classLibrary you can have the required control.
+
+```java
+/* new ClassLibrary() will give you an empty classLoader
+ * Big chance you want at least the system classloader.
+ */
+ClassLibraryBuilder libraryBuilder = new SortedClassLibraryBuilder(); //or OrderedClassLibraryBuilder()
+libraryBuilder.addClassLoader( ClassLoader.getSystemClassLoader() );
+JavaProjectBuilder builder = new JavaProjectBuilder( libraryBuilder );
+```
+
+## I'm getting an ArrayIndexOutOfBoundsException: 500. What to do?
+
+During the parsing of java files the Parser needs to remember states, which are kept in a stack. Due to recursive calls the stack can become very large. By default the size of this this stack is 500 and it can only be set during compile-time of QDox. Normally 500 per sourcefile will do, but in very, very rare cases this might be too little. The only way to increase this number is by rebuilding it. Download the sources and build it like mvn install -Dqdox.javaparser.stack=750 if you want  [...]
+
+# Download
+
+QDox is available at the Maven Central. To include the most recent of QDox in your pom, include the following dependency:
+
+```xml
+  	 <dependency>
+  	   <groupId>${project.groupId}</groupId>
+  	   <artifactId>${project.artifactId}</artifactId>
+  	   <version>${project.version}</version>
+  	 </dependency>
+```
+
+Latest stable release - QDox ${project.rel.org.thoughtworks.qdox:qdox}: binary jar | sources jar | javadoc jar | project tar.bz2 | project tar.gz | project zip
+
+# What is using QDox
+
+Project	Description	How QDox is Used
+AspectWerkz	AspectWerkz is an Aspect Oriented Programming (AOP) toolkit for Java that modifies byte-code to weave in interceptors and mixins.	Attributes can be used to associate interceptors and mixins with a specific class.
+
+## Avalon Phoenix
+
+Phoenix was a micro-kernel designed and implemented on top of the Avalon framework. It provided a number of facilities to manage the environment of Server Applications. Apache cancelled the Avalon project 2004	'MetaGenerate' is part of the Phoenix toolset and picks up @phoenix prefixed JavaDoc tags to make XML manifests for the components that will be laced together in more XML to make a complete server application.
+
+## Cocoon
+Apache Cocoon is an XML publishing framework that raises the usage of XML and XSLT technologies for server applications to a new level. Designed for performance and scalability around pipelined SAX processing, Cocoon offers a flexible environment based on a separation of concerns between content, logic, and style.	The QDox Block reads in Java source files and fires out SAX events enabling processing by standard XML tools (such as XSLT).
+
+## Commons Attribute
+
+Jakarta Commons Attributes provides an API to runtime metadata attributes. Attributes are specified as doclet tags and then compiled into the classpath where they can be accessed at runtime (without requiring the source). The aim is to provide a framework similar to .NET attributes.	QDox is used to extract the JavaDoc tags from the source files.
+
+## GWT-maven-plugin
+
+The gwt-maven-plugin provides support for GWT projects, including running the GWT developer tools (the compiler, shell and i18n generation) and performing support operations to help developers make GWT fit more closely in with their standard JEE web application development (debugging, managing the embedded server, running noserver, merging web.xml, generating I18N interfaces, generating Async GWT-RPC interfaces, and more) and environment (Eclipse IDE).	QDox is used to generate the Async  [...]
+
+## Ivory
+
+Ivory provides easy integration between your exiting Java classes, Avalon services, and Axis. It allows easy deployment of soap services with none of the WSDD configuration that Axis normally mandates.	Attributes are used to provide additional hints to Ivory about Java classes that cannot be determined via reflection.
+
+## maven-javadoc-plugin
+
+The Javadoc Plugin uses the Javadoc tool to generate javadocs for the specified project.	When developers write code, they could forget to create (or update) the Javadoc comments. The <fix> and <test-fix> goals are interactive goals to fix the actual Javadoc comments.
+
+Maven 2 & 3
+
+## Maven is a software project management and comprehension tool.	QDox is used for extraction of Javadoc tags from source files to generate plugin descriptors
+
+## Mock Maker
+
+Mock Maker is a tool for automatically generating mock objects from custom classes to aid in testing the untestable. This supports the practises of Test Driven Development and eXtreme Programming. Mock Maker scans the source repository for any class/interface marked with the @mock JavaDoc tag and automatically creates the Mock Object for this that matches the class definition.
+
+## Nanning
+
+Nanning is an Aspect Oriented Programming (AOP) toolkit for Java that does not require a custom compiler. It uses dynamic proxies to weave in interceptors and mixins at runtime.	QDox is used to allow aspects to be applied to classes by specifiying meta-data in doclet tags.
+
+## Paranamer
+
+Paranamer a mechamism for accessing the parameter names of methods of Java classes compiled into jars. QDox is used to parse the source and generate the parameter names list.
+
+## Spring ME
+
+A version of Spring that not only has a very small runtime footprint (none), but also is capable of running on small handheld devices, since it does not rely on reflection.
+
+## vDoclet
+
+vDoclet is a framework for code-generation using Velocity templates, based on annotated Java source-code. vDoclet uses QDox to produce input-data for it's templates.
+
+## Voruta
+
+Voruta is a data access framework for embedding SQL statements in Java methods using custom JavaDoc tags and dynamic code generation at runtime. QDox is used to parse metadata and CGLib to generate implementation at runtime.
+
+## XDoclet2
+
+XDoclet2 is a framework for code-generation using Velocity or Jelly templates, based on annotated Java source-code. It is a rewrite of XDoclet.
+
+XDoclet2 uses QDox to produce input-data for it's templates, as well as QDox' APITestCase to validate the generated sources.
+
+# QDox Usage
+
+## Entry Point
+
+JavaProjectBuilder is the entry point to QDox. It is responsible for parsing source code, resolving imports and storing the data.
+
+To create it, all you need to do is call the default constructor.
+
+```java
+JavaProjectBuilder builder = new JavaProjectBuilder();
+```
+
+## Reading Source Files
+
+Java source code can then be added to the JavaProjectBuilder. Source can either be read one file at a time (using a java.io.Reader) or an entire source tree can be added recursively.
+
+```java
+// Reading a single source file.
+builder.addSource(new FileReader("MyFile.java"));
+
+// Reading from another kind of input stream.
+builder.addSource(new StringReader("package test; public class Hello {}"));
+
+// Adding all .java files in a source tree (recursively).
+builder.addSourceTree(new File("mysrcdir"));
+```
+
+## Resolving Class Names
+
+In order to resolve classes that have been imported using a wildcard (e.g. import java.util.*;), the ClassLibrary must be aware of other classes used in the project.
+
+ClassLibrary has 4 ways to resolve classes:
+
+* By looking at other sources that have been added.
+* By searching through the supplied sourceFolders
+* By looking in the current classpath (including the standard JRE classes).
+* By looking at additional ClassLoaders specified at runtime.
+
+All sources and sourcetrees added to the JavaProjectBuilder will be parsed. This is often much more than required. To increase efficiency use the ClassLibrary to add sourcefolders. Consider these files as lazy parsed sources.
+
+The current classpath is automatically set by JavaProjectBuilder. In most cases this shall be sufficient, however in some situations you may want resolve the full classes in external libraries.
+
+```java
+// Get the ClassLibrary
+JavaProjectBuilder builder = new JavaProjectBuilder();
+
+// Add a sourcefolder;
+builder.addSourceFolder( new File( "src/main/java" ) );
+builder.addSourceFolder( new File( "target/generated-sources/foobar" ) );
+
+// Add a custom ClassLoader
+builder.addClassLoader( myCustomClassLoader );
+
+// Ant example : add the <classpath> element's contents
+builder.addClassLoader( new AntClassLoader( getProject(), classpath ) );
+```
+
+It is important that additional ClassLoaders are added before any source files are parsed.
+
+## Navigating The Model
+
+Now the files have been parsed, move on to navigating the model.
+
+# The Model
+
+After the source code has been parsed, the content of the files can be navigated using a simple to use and intuitive object model.
+
+## JavaSource
+
+Represents a complete .java file. This contains a collection of classes.
+
+Example Input
+
+```java
+package com.blah.foo;
+
+import java.awt.*;
+import java.util.List;
+
+public class Class1 {
+  ...
+}
+
+class Class2 {
+}
+
+interface Interface1 {
+}
+```
+
+```java            
+Example Code
+JavaProjectBuilder builder = new JavaProjectBuilder();
+JavaSource src = builder.addSource(myReader);
+
+JavaPackage pkg      = src.getPackage();
+List<String> imports     = src.getImports(); // {"java.awt.*",
+                                     //  "java.util.List"}
+
+JavaClass class1     = src.getClasses().get(0);
+JavaClass class2     = src.getClasses().get(1);
+JavaClass interface1 = src.getClasses().get(2);
+```    
+
+## JavaPackage
+
+Represents the package of the class.
+
+Example input
+
+```java
+package com.blah.foo;
+
+public class BarClass  {
+...
+}
+ ```
+
+Example Code
+
+```java
+JavaProjectBuilder builder = new JavaProjectBuilder();
+JavaSource src = builder.addSource(myReader);
+
+JavaPackage pkg      = src.getPackage();
+
+Collection<JavaClass> classes  = pkg.getClasses(); // BarClass
+String name          = pkg.getName(); // "com.blah.foo"
+String toString      = pkg.toString(); // "package com.blah.foo" conform javaAPI
+JavaPackage parent   = pkg.getParentPackage(); //
+```
+
+## JavaClass
+
+Represents a class or interface. This contains doclet tags, fields and methods. Information about the class definition is available, such as which classes are extended, which interfaces implemented and modifiers.
+
+```java
+Example Input
+package com.blah.foo;
+
+import java.io.*;
+import com.custom.*;
+import com.base.SubClass;
+
+/**
+ * @author Joe
+ */
+public abstract class MyClass extends SubClass
+            implements Serializable, CustomInterface  {
+
+  private String name;
+  public void doStuff() { ... }
+  private int getNumber() { ... }
+
+}
+```
+
+Example Code
+
+```java
+JavaProjectBuilder builder = new JavaProjectBuilder();
+builder.addSource(myReader);
+
+JavaClass cls = builder.getClassByName("com.blah.foo.MyClass");
+
+String pkg      = cls.getPackage();            // "com.blah.foo"
+String name     = cls.getName();               // "MyClass"
+String fullName = cls.getCanonicalName(); // "com.blah.foo.MyClass";
+String canonicalName = cls.getFullyQualifiedName(); // "com.blah.foo.MyClass";
+boolean isInterface = cls.isInterface();       // false
+
+boolean isPublic   = cls.isPublic();   // true
+boolean isAbstract = cls.isAbstract(); // true
+boolean isFinal    = cls.isFinal();    // false
+
+JavaType superClass = cls.getSuperClass(); // "com.base.SubClass";
+List<JavaType> imps     = cls.getImplements(); // {"java.io.Serializable",
+                                       //  "com.custom.CustomInterface"}
+
+String author = cls.getTagsByName("author").getValue(); // "joe"
+
+JavaField nameField = cls.getFields()[0];
+JavaMethod doStuff = cls.getMethods()[0];
+JavaMethod getNumber = cls.getMethods()[1];
+
+JavaSource javaSource = cls.getParentSource();
+```
+
+## JavaField
+
+Represents a field in a class. This has doclet tags, a name and a type.
+
+Example Input
+
+```java
+import java.util.Date;
+
+public class MyClass  {
+
+  /**
+   * @magic
+   */
+  private String email;
+
+  public static Date[][] dates;
+
+}
+```    
+
+Example Code
+
+```java
+JavaField e = cls.getFields()[0];
+
+JavaType eType     = e.getType(); // "java.lang.String";
+String eName   = e.getName(); // "email";
+DocletTag eTag = e.getTagsByName("magic"); // @magic
+boolean eArray = e.getType().isArray(); // false;
+
+JavaField d = cls.getFields()[1];
+
+JavaType dType     = d.getType(); // "java.util.Date";
+String dName   = d.getName(); // "dates";
+DocletTag dTag = d.getTagsByName("magic"); // null
+boolean dArray = d.getType().isArray(); // true;
+int dDimensions= d.getType().getDimensions(); // 2;
+boolean dStatic= d.isStatic(); // true;
+
+JavaClass javaClass = d.getParentClass();
+```
+
+## JavaMethod
+
+Represents a method in a class. This has doclet tags, a name, return type, parameters and exceptions.
+
+Example Input
+
+```java
+import java.util.Date;
+import java.io.*;
+
+public class MyClass  {
+
+  /**
+   * @returns Lots of dates
+   */
+  public static Date[] doStuff(int number,
+                               String stuff)
+            throws RuntimeException, IOException {
+    ...
+  }
+
+}
+```
+
+Example Code
+
+```java
+JavaMethod m = cls.getMethods()[0];
+
+String mName = m.getName(); // "doStuff";
+JavaType mReturns = m.getReturns(); // "java.util.Date";
+boolean mArray = m.getReturns().isArray(); // true
+boolean mStatic = m.isStatic(); // true
+boolean mPublic = m.isPublic(); // true
+
+String doc = m.getTagByName("returns").getValue();
+  // "Lots of dates"
+
+List<JavaType> exceptions = m.getExceptions();
+  // {"java.lang.RuntimeException", "java.io.IOException"}
+
+JavaParameter numberParam = m.getParameters()[0];
+JavaParameter stuffParam = m.getParameters()[1];
+
+JavaClass javaClass = m.getParentClass();
+```
+
+## JavaParameter
+
+Represents a parameter passed to a method. This has a name and a type.
+
+```java
+Example Input
+public class MyClass  {
+
+  public void stuff(int n, Object[] objects) {
+    ...
+  }
+
+}
+```
+
+Example Code
+
+```java
+JavaMethod m = cls.getMethods()[0];
+
+JavaParameter n = m.getParameters()[0];
+String nName = n.getName(); // "n"
+JavaType nType   = n.getType(); // "int";
+
+JavaParameter o = m.getParameters()[1];
+String oName   = o.getName(); // "objects"
+JavaType oType     = o.getType(); // "java.lang.Object";
+boolean oArray = o.getType().isArray(); // true
+
+JavaMethod javaMethod = o.getParentMethod();
+```
+
+## JavaType
+
+Represents a specific instance of a class used by another class (such as return value, superclass, etc). The value represents the name of the class. Array dimensions are also available. Since 1.8 it's also possible to get the generic value of the Type
+
+Example Input
+
+```java  
+import java.util.*;
+
+public class MyClass  {
+
+  public void stuff(int n, Object[] objects,
+	                  Date[][] dates, List<String> stringList) {
+    ...
+  }
+
+}
+```    
+
+Example Code
+
+
+```java
+JavaMethod m = cls.getMethods()[0];
+
+JavaType returns = m.getReturns();
+returns.getValue(); // "void"
+returns.isArray(); // false
+returns.getDimensions(); // 0
+
+JavaType n = m.getParameters()[0].getType();
+n.getValue(); // "int"
+n.isArray(); // false
+n.getDimensions(); // 0
+
+JavaType objects = m.getParameters()[1].getType();
+objects.getValue(); // "java.lang.Object"
+objects.isArray(); // true
+objects.getDimensions(); // 1
+
+JavaType dates = m.getParameters()[2].getType();
+dates.getValue(); // "java.util.Date"
+dates.isArray(); // true
+dates.getDimensions(); // 2
+
+JavaType stringList = m.getParameters()[3].getType();
+stringList.getValue(); // "java.util.List"
+stringList.getGenericValue(); // "java.util.List<java.lang.String>"
+stringList.isArray(); // false
+stringList.getDimensions(); // 0
+```
+
+## DocletTag
+
+Represents a JavaDoc tag. Each tag has a name and a value. Optionally, the value can be broken up into tokens accessed by index or name.
+
+The JavaClass, JavaField and JavaMethod classes all support comments and DocletTags
+
+The returned DocletTag carries the name, value and methods for breaking up the value into specific parameters.
+
+Example Input
+
+```java
+/**
+ * This method does nothing at all.
+ *
+ * @returns A boolean of whether we care or not.
+ * @param email Someone's email address.
+ * @param dob Date of birth.
+ *
+ * @permission administrator full-access
+ * @webservice publish=true name=myservice type=rpc
+ */
+boolean doWeCare(String email, Date dob);
+```
+
+Example Code
+
+```java
+JavaMethod mth = cls.getMethods()[0];
+
+// Access the JavaDoc comment
+String comment = mth.getComment();
+// "This method does nothing at all."
+
+// Access a single doclet tag
+DocletTag returns = mth.getTagByName("returns");
+returns.getName(); // "returns";
+returns.getValue(); // "A boolean of whether we care or not."
+
+// Access multiple doclet tags with the same name
+DocletTag[] params = mth.getTagsByName("param");
+params[0].getValue(); // "Someone's email address."
+params[1].getValue(); // "Date of birth."
+
+// Access specific parameters of a doclet tag by index
+DocletTag permission = mth.getTagByName("permission");
+permission.getParameter[0]; // "administrator"
+permission.getParameter[1]; // "full-access"
+
+// Access specific parameters of a doclet tag by name
+DocletTag webservice = mth.getTagByName("webservice");
+webservice.getNamedParameter("type"); // "rpc"
+webservice.getNamedParameter("name"); // "myservice"
+```
+
+# Building QDox
+
+Snapshot deployments: snapshots directory.
+
+To build QDox there are two prerequisites:
+
+Key Dependencies:
+
+1. [Maven 3](http://maven.apache.org)
+
+2. [BYacc/J](http://byaccj.sourceforge.net)
+
+Paarser generator used to create an effective parser for JavaDoc.
+If using Windows, Linux, Solaris or Mac OS X, no additional installation is
+needed as yacc binaries are supplied in the bootstrap directory.
+If using any other platform, download BYacc/J from the site or build it yourself, in which case
+we would be grateful to receive a copy of your binary, so we can upgrade the bootstrap support.
+
+Build goals:
+
+mvn package				- Create qdox jar
+mvn generate-sources 	- Generate the Java parser code (allowing you to develop in an IDE).
+mvn site      			- Build the QDox website
+mvn release:prepare		- Prepare release (confirm or change release version interactively)
+mvn release:perform		- Perform release (perform release from tag of prepare phase)
diff --git a/README.txt b/README.txt
deleted file mode 100644
index e227b15..0000000
--- a/README.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-To build QDox there are two prerequisites:
-
-* Maven 2 (2.0.9 or later)
-http://maven.apache.org
- 
-* BYacc/J (1.8 or later)
-http://byaccj.sourceforge.net/
-Paarser generator used to create an effective parser for JavaDoc.
-If using Windows, Linux, Solaris or Mac OS X, no additional installation is 
-needed as yacc binaries are supplied in the bootstrap directory. 
-If using any other platform, download BYacc/J from the site or build it yourself, in which case
-we would be grateful to receive a copy of your binary, so we can upgrade the bootstrap support.
-
-Build goals:
-
-mvn install				- Create qdox jar
-mvn generate-sources 	- Generate the Java parser code (allowing you to develop in an IDE).
-mvn site      			- Build the QDox website
-mvn release:prepare		- Prepare release (confirm or change release version interactively)
-mvn release:perform		- Perform release (perform release from tag of prepare phase)
-
-If you are releasing, remember to 
-
-1) Update src/site/content/download.html
-2) Go to JIRA and release the applicable version for QDOX : http://jira.codehaus.org/secure/project/ManageVersions.jspa?pid=10103
-3) Copy the contents of target/site/ to the DAV folder for QDox's website : https://dav.codehaus.org/qdox/
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 5b1c760..229132a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,17 +2,17 @@
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <groupId>org.codehaus</groupId>
-    <artifactId>codehaus-parent</artifactId>
-    <version>4</version>
+    <groupId>org.sonatype.oss</groupId>
+    <artifactId>oss-parent</artifactId>
+    <version>9</version>
   </parent>
 
   <name>QDox</name>
   <groupId>com.thoughtworks.qdox</groupId>
   <artifactId>qdox</artifactId>
-  <version>2.0-M3</version>
-  <packaging>jar</packaging>
-  <url>http://qdox.codehaus.org</url>
+  <version>2.0-M6</version>
+
+  <url>https://github.com/paul-hammant/qdox</url>
   <description>
     QDox is a high speed, small footprint parser for extracting class/interface/method definitions from source files
     complete with JavaDoc @tags. It is designed to be used by active code generators or documentation tools.
@@ -27,49 +27,16 @@
     </license>
   </licenses>
 
-  <mailingLists>
-    <mailingList>
-      <name>announce at QDox</name>
-      <post>announce at qdox.codehaus.org</post>
-      <subscribe>announce-subscribe at qdox.codehaus.org</subscribe>
-      <unsubscribe>announce-unsubscribe at qdox.codehaus.org</unsubscribe>
-      <archive>http://archive.codehaus.org/lists/org.codehaus.qdox.announce</archive>
-    </mailingList>
-    <mailingList>
-      <name>dev at QDox</name>
-      <post>dev at qdox.codehaus.org</post>
-      <subscribe>dev-subscribe at qdox.codehaus.org</subscribe>
-      <unsubscribe>dev-unsubscribe at qdox.codehaus.org</unsubscribe>
-      <archive>http://archive.codehaus.org/lists/org.codehaus.qdox.dev</archive>
-    </mailingList>
-    <mailingList>
-      <name>scm at QDox</name>
-      <subscribe>scm-subscribe at qdox.codehaus.org</subscribe>
-      <unsubscribe>scm-unsubscribe at qdox.codehaus.org</unsubscribe>
-      <archive>http://archive.codehaus.org/lists/org.codehaus.qdox.scm</archive>
-    </mailingList>
-    <mailingList>
-      <name>user at QDox</name>
-      <post>user at qdox.codehaus.org</post>
-      <subscribe>user-subscribe at qdox.codehaus.org</subscribe>
-      <unsubscribe>user-unsubscribe at qdox.codehaus.org</unsubscribe>
-      <archive>http://archive.codehaus.org/lists/org.codehaus.qdox.user</archive>
-    </mailingList>
-  </mailingLists>
-
   <issueManagement>
-    <system>jira</system>
-    <url>http://jira.codehaus.org/browse/QDOX</url>
+    <system>github</system>
+    <url>https://github.com/paul-hammant/qdox/issues</url>
   </issueManagement>
-  <ciManagement>
-    <system>bamboo</system>
-    <url>http://bamboo.ci.codehaus.org/browse/QDOX</url>
-  </ciManagement>
 
   <scm>
-    <connection>scm:svn:https://svn.codehaus.org/qdox/tags/qdox-2.0-M3</connection>
-    <developerConnection>scm:svn:https://svn.codehaus.org/qdox/tags/qdox-2.0-M3</developerConnection>
-    <url>http://svn.qdox.codehaus.org/browse/qdox/tags/qdox-2.0-M3</url>
+    <connection>scm:git:https://github.com/paul-hammant/qdox.git</connection>
+    <developerConnection>scm:git:ssh://git@github.com/paul-hammant/qdox.git</developerConnection>
+    <url>https://github.com/paul-hammant/qdox</url>
+    <tag>qdox-2.0-M6</tag>
   </scm>
 
   <developers>
@@ -154,15 +121,14 @@
     </contributor>
   </contributors>
 
+  <properties>
+    <maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <timestamp>${maven.build.timestamp}</timestamp>
+    <qdox.javaparser.stack>500</qdox.javaparser.stack>
+  </properties>
+  
   <build>
-    <extensions>
-      <extension>
-        <groupId>org.apache.maven.wagon</groupId>
-        <artifactId>wagon-webdav-jackrabbit</artifactId>
-        <version>2.2</version>
-      </extension>
-    </extensions>
-
     <pluginManagement>
       <plugins>
         <plugin>
@@ -178,9 +144,9 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-surefire-plugin</artifactId>
-          <version>2.9</version>
+          <version>2.19.1</version>
           <configuration>
-            <forkMode>always</forkMode>
+            <reuseForks>false</reuseForks>
           </configuration>
         </plugin>
         <plugin>
@@ -325,7 +291,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-failsafe-plugin</artifactId>
-        <version>2.9</version>
+        <version>2.19.1</version>
         <executions>
           <execution>
             <goals>
@@ -338,7 +304,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-invoker-plugin</artifactId>
-        <version>1.5</version>
+        <version>2.0.0</version>
         <configuration>
           <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
           <postBuildHookScript>verify</postBuildHookScript>
@@ -398,14 +364,6 @@
     </dependency>
   </dependencies>
 
-  <distributionManagement>
-    <site>
-      <id>codehaus.org</id>
-      <name>QDox Site</name>
-      <url>dav:https://dav.codehaus.org/qdox/</url>
-    </site>
-  </distributionManagement>
-
   <profiles>
     <profile>
       <id>linux</id>
@@ -475,7 +433,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-project-info-reports-plugin</artifactId>
-        <version>2.4</version>
+        <version>2.8</version>
         <reportSets>
           <reportSet>
             <reports>
@@ -523,32 +481,7 @@
           </reportSet>
         </reportSets>
       </plugin>
-
-      <!-- Manual Changelist -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-changes-plugin</artifactId>
-        <version>2.6</version>
-        <configuration>
-          <!-- jira-report -->
-          <columnNames>Key,Summary,Fix Version,Status,Resolution</columnNames>
-          <sortColumnNames>Fix Version DESC, Priority DESC, Created DESC</sortColumnNames>
-          <statusIds>Resolved, Closed</statusIds>
-        </configuration>
-        <reportSets>
-          <reportSet>
-            <reports>
-              <report>jira-report</report>
-            </reports>
-          </reportSet>
-        </reportSets>
-      </plugin>
     </plugins>
   </reporting>
-  <properties>
-    <maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <timestamp>${maven.build.timestamp}</timestamp>
-    <qdox.javaparser.stack>500</qdox.javaparser.stack>
-  </properties>
+
 </project>
diff --git a/src/grammar/commentlexer.flex b/src/grammar/commentlexer.flex
index d674699..1bb0fb5 100644
--- a/src/grammar/commentlexer.flex
+++ b/src/grammar/commentlexer.flex
@@ -105,6 +105,11 @@ JavadocEnd              = "*"+ "/"
   "/**/" { 
            codeBody.append( "/**/" ); 
          }
+  "/**" [*]+ "/" { 
+           yypushback(2);
+           pushState(JAVADOC);
+           return DefaultJavaCommentParser.JAVADOCSTART; 
+         }
   "/*" [*]+ {
            pushState( JAVADOC );
            pushState( JAVADOCCONTENT );
diff --git a/src/grammar/lexer.flex b/src/grammar/lexer.flex
index 98504be..93a1a00 100644
--- a/src/grammar/lexer.flex
+++ b/src/grammar/lexer.flex
@@ -182,18 +182,37 @@ Id						        = ([:jletter:]|{UnicodeChar}) ([:jletterdigit:]|{UnicodeChar})*
 Annotation                      = "@" {WhiteSpace}* {Id} ("."{Id})* {WhiteSpace}*
 JavadocEnd                      = "*"+ "/"
 
-%state JAVADOC JAVADOCTAG JAVADOCLINE CODEBLOCK PARENBLOCK ASSIGNMENT STRING CHAR SINGLELINECOMMENT MULTILINECOMMENT ANNOTATIONTYPE ANNOTATION ANNOSTRING ANNOCHAR ENUM ARGUMENTS
+%state JAVADOC JAVADOCTAG JAVADOCLINE CODEBLOCK PARENBLOCK ASSIGNMENT STRING CHAR SINGLELINECOMMENT MULTILINECOMMENT  ANNOTATION ANNOSTRING ANNOCHAR ARGUMENTS NAME 
+%state ANNOTATIONTYPE ENUM MODULE TYPE ANNOTATIONNOARG
 
 %%
-
-<YYINITIAL, ANNOTATIONTYPE, ENUM> {
+<YYINITIAL> {
+    "open"              { return Parser.OPEN; }
+    "module"            { pushState(MODULE);
+                          return Parser.MODULE; }
+}
+<NAME>
+{
+  ";"  { popState();
+         return Parser.SEMI; }
+  "{"  {  popState();
+          yypushback(1);     }
+  "("  {  popState();
+          yypushback(1);     }
+}
+<ANNOTATIONNOARG> {
+  {WhiteSpace} { popState(); }
+}
+<YYINITIAL, ANNOTATIONNOARG, ANNOTATIONTYPE, ENUM, NAME, TYPE> {
     "."                 { return Parser.DOT; }
     "..."               { return Parser.DOTDOTDOT; }
     ","                 { return Parser.COMMA; }
     "*"                 { return Parser.STAR; }
 
-    "package"           { return Parser.PACKAGE; }
-    "import"            { return Parser.IMPORT; }
+    "package"           { pushState(NAME);
+                          return Parser.PACKAGE; }
+    "import"            { pushState(NAME);
+                          return Parser.IMPORT; }
     "public"            { return Parser.PUBLIC; }
     "protected"         { return Parser.PROTECTED; }
     "private"           { return Parser.PRIVATE; }
@@ -227,28 +246,33 @@ JavadocEnd                      = "*"+ "/"
 
     "class"             {
         classDepth++;
-        braceMode = YYINITIAL;
+        braceMode = TYPE;
+        pushState(NAME);
         return Parser.CLASS; 
     }
     
     "interface"         { 
         classDepth++;
-        braceMode = YYINITIAL;
+        braceMode = TYPE;
+        pushState(NAME);
         return Parser.INTERFACE;
     }
     
     "enum"              {
         classDepth++;
         braceMode = ENUM;
+        pushState(NAME);
         return Parser.ENUM;
     }
     {Annotation} "(" {
         parenMode = ANNOTATION;
         yypushback(text().length()-1);
         getCodeBody(); /* reset codebody */
+        pushState(NAME);
         return Parser.AT;
     }
     "@"                 {
+        pushState(ANNOTATIONNOARG);
         return Parser.AT;
     }
     "{"                 {
@@ -267,7 +291,7 @@ JavadocEnd                      = "*"+ "/"
           nestingDepth++;
           if (enumConstantMode && yystate() == ENUM)
           {
-            braceMode = YYINITIAL;
+            braceMode = TYPE;
           }
           else 
           {
@@ -282,7 +306,7 @@ JavadocEnd                      = "*"+ "/"
         popState();
         if ( yystate() == ENUM && enumConstantMode)
         {
-          braceMode = YYINITIAL;
+          braceMode = TYPE;
         }
         else
         {
@@ -304,7 +328,7 @@ JavadocEnd                      = "*"+ "/"
         pushState(ASSIGNMENT);
     }
 }
-<YYINITIAL, ANNOTATIONTYPE> {
+<YYINITIAL, ANNOTATIONTYPE, TYPE> {
     ";"  { return Parser.SEMI; }
     "("  {
             nestingDepth++;
@@ -316,6 +340,26 @@ JavadocEnd                      = "*"+ "/"
             return Parser.PARENOPEN;
           }
 }
+<MODULE> {
+	"{"                 { return Parser.BRACEOPEN; }
+    "}"                 { popState(); 
+                          return Parser.BRACECLOSE; }
+
+    ","                 { return Parser.COMMA; }
+	"."                 { return Parser.DOT; }
+	";"                 { return Parser.SEMI; }
+	
+    "exports"           { return Parser.EXPORTS; }
+    "opens"             { return Parser.OPENS; }
+    "provides"          { return Parser.PROVIDES; }
+    "public"            { return Parser.PUBLIC; }
+    "requires"          { return Parser.REQUIRES; }
+    "static"            { return Parser.STATIC; }
+    "transitive"        { return Parser.TRANSITIVE; }
+    "to"                { return Parser.TO; }
+    "uses"              { return Parser.USES; }
+    "with"              { return Parser.WITH; }
+}
 <ENUM> {
     ";"  { 
     		enumConstantMode = false; 
@@ -341,13 +385,13 @@ JavadocEnd                      = "*"+ "/"
             }
          }
 }
-<YYINITIAL, ENUM> {
+<ENUM, TYPE> {
     "default"           { return Parser.DEFAULT; }
 }
 <ANNOTATIONTYPE> {
 	"default"           { assignmentDepth = nestingDepth; appendingToCodeBody = true; pushState(ASSIGNMENT); }
 }
-<YYINITIAL, ANNOTATIONTYPE, ENUM> {
+<YYINITIAL, ANNOTATIONNOARG, ANNOTATIONTYPE, ENUM, MODULE, NAME, TYPE> {
     {Id} {
         return Parser.IDENTIFIER;
     }
@@ -370,6 +414,17 @@ JavadocEnd                      = "*"+ "/"
     }
 }
 
+<ANNOTATION> {
+	"{"                 { nestingDepth++; return Parser.BRACEOPEN; }
+    "}"                 { nestingDepth--; return Parser.BRACECLOSE; }
+}
+<ARGUMENTS> {
+	"{"                 { pushState(CODEBLOCK);
+                          braceMode = -1;
+                          yypushback(1); /* (re)enter brace in right mode */ }
+    "}"                 { return Parser.BRACECLOSE; }
+}
+
 <ANNOTATION,ARGUMENTS> {
 	"("                 { ++ nestingDepth; return Parser.PARENOPEN; }
     ")"                 { if( nestingDepth-- == annotationDepth) { popState(); } return Parser.PARENCLOSE; }
@@ -390,9 +445,6 @@ JavadocEnd                      = "*"+ "/"
     
     "++"                { return Parser.PLUSPLUS; }
     "--"                { return Parser.MINUSMINUS; }
-    
-	"{"                 { nestingDepth++; return Parser.BRACEOPEN; }
-    "}"                 { nestingDepth--; return Parser.BRACECLOSE; }
 
 	"\""                { appendingToCodeBody=true; codeBody.append("\""); pushState(ANNOSTRING); }
     "\'"                { appendingToCodeBody=true; codeBody.append("\'"); pushState(ANNOCHAR); }
@@ -400,6 +452,7 @@ JavadocEnd                      = "*"+ "/"
 	"."                 { return Parser.DOT; }
 
     "?"                 { return Parser.QUERY; }
+    "::"                { return Parser.COLONCOLON; }
     ":"                 { return Parser.COLON; }
     "<<"                { return Parser.LESSTHAN2; }
     ">>>"               { return Parser.GREATERTHAN3; }
@@ -550,12 +603,12 @@ JavadocEnd                      = "*"+ "/"
     }
 }
 
-<ASSIGNMENT, YYINITIAL, CODEBLOCK, PARENBLOCK, ENUM, ANNOTATIONTYPE> {
+<ASSIGNMENT, YYINITIAL, CODEBLOCK, PARENBLOCK, ENUM, ANNOTATIONTYPE, TYPE> {
     "\""                { if (appendingToCodeBody) { codeBody.append('"');  } pushState(STRING); }
     \'                  { if (appendingToCodeBody) { codeBody.append('\''); } pushState(CHAR); }
 }
 
-<ASSIGNMENT, YYINITIAL, CODEBLOCK, PARENBLOCK, ENUM, ANNOTATIONTYPE, ANNOTATION, ARGUMENTS> {
+<ASSIGNMENT, YYINITIAL, CODEBLOCK, PARENBLOCK, ENUM, ANNOTATIONTYPE, ANNOTATION, ARGUMENTS, TYPE, NAME> {
   "//"                { if (appendingToCodeBody) { codeBody.append("//"); } pushState(SINGLELINECOMMENT); }
   "/*"                { if (appendingToCodeBody) { codeBody.append("/*"); } pushState(MULTILINECOMMENT); }
   "/**/"              { if (appendingToCodeBody) { codeBody.append("/**/"); } }
diff --git a/src/grammar/parser.y b/src/grammar/parser.y
index a96321d..2a98b83 100644
--- a/src/grammar/parser.y
+++ b/src/grammar/parser.y
@@ -31,6 +31,7 @@ import java.util.Stack;
 %token SEMI DOT DOTDOTDOT COMMA STAR PERCENT EQUALS ANNOSTRING ANNOCHAR SLASH PLUS MINUS
 %token STAREQUALS SLASHEQUALS PERCENTEQUALS PLUSEQUALS MINUSEQUALS LESSTHAN2EQUALS GREATERTHAN2EQUALS GREATERTHAN3EQUALS AMPERSANDEQUALS CIRCUMFLEXEQUALS VERTLINEEQUALS 
 %token PACKAGE IMPORT PUBLIC PROTECTED PRIVATE STATIC FINAL ABSTRACT NATIVE STRICTFP SYNCHRONIZED TRANSIENT VOLATILE DEFAULT
+%token OPEN MODULE REQUIRES TRANSITIVE EXPORTS OPENS TO USES PROVIDES WITH
 %token CLASS INTERFACE ENUM ANNOINTERFACE THROWS EXTENDS IMPLEMENTS SUPER DEFAULT NEW
 %token BRACEOPEN BRACECLOSE SQUAREOPEN SQUARECLOSE PARENOPEN PARENCLOSE
 %token LESSTHAN GREATERTHAN LESSEQUALS GREATEREQUALS
@@ -38,7 +39,7 @@ import java.util.Stack;
 %token EXCLAMATION AMPERSAND2 VERTLINE2 EQUALS2 NOTEQUALS
 %token TILDE AMPERSAND VERTLINE CIRCUMFLEX
 %token VOID
-%token QUERY COLON AT
+%token QUERY COLON COLONCOLON AT
 %token CODEBLOCK PARENBLOCK
 %token BYTE SHORT INT LONG CHAR FLOAT DOUBLE BOOLEAN
 
@@ -59,10 +60,10 @@ import java.util.Stack;
 %type <annoval> Expression Literal Annotation ElementValue ElementValueArrayInitializer
 %type <annoval> ConditionalExpression ConditionalOrExpression ConditionalAndExpression InclusiveOrExpression ExclusiveOrExpression AndExpression
 %type <annoval> EqualityExpression RelationalExpression ShiftExpression AdditiveExpression MultiplicativeExpression
-%type <annoval> UnaryExpression UnaryExpressionNotPlusMinus PreIncrementExpression PreDecrementExpression Primary PrimaryNoNewArray ArrayCreationExpression MethodInvocation ClassInstanceCreationExpression
+%type <annoval> UnaryExpression UnaryExpressionNotPlusMinus PreIncrementExpression PreDecrementExpression Primary PrimaryNoNewArray ArrayCreationExpression MethodInvocation MethodReference ClassInstanceCreationExpression
 %type <annoval> PostfixExpression PostIncrementExpression PostDecrementExpression CastExpression Assignment LeftHandSide AssignmentExpression
 %type <ival> Dims Dims_opt
-%type <sval> QualifiedIdentifier TypeDeclSpecifier MethodBody AssignmentOperator
+%type <sval> QualifiedIdentifier TypeDeclSpecifier MethodBody AssignmentOperator ModuleName
 %type <type> Type ReferenceType Wildcard WildcardBounds VariableDeclaratorId ClassOrInterfaceType TypeArgument
 
 %%
@@ -74,30 +75,127 @@ import java.util.Stack;
 // ------------------------------
 
 // CompilationUnit:
-//     [PackageDeclaration] {ImportDeclaration} {TypeDeclaration}  
-CompilationUnit: PackageDeclaration_opt ImportDeclarations_opt TypeDeclarations_opt
+//     [PackageDeclaration] {ImportDeclaration} {TypeDeclaration}
+//     {ImportDeclaration} ModuleDeclaration  
+CompilationUnit: CompilationDeclaration
+               | CompilationUnit CompilationDeclaration
                ;
 
+CompilationDeclaration: Annotation
+                      | ImportDeclaration
+                      | ModuleDeclaration
+                      | PackageDeclaration
+                      | TypeDeclaration
+                      ;
+
+// ModuleDeclaration:
+//    {Annotation} [open] module ModuleName { {ModuleStatement} }
+ModuleDeclaration: OPEN MODULE ModuleName
+                   {
+                     ModuleDef module = new ModuleDef($3);
+                     module.setOpen(true);
+                     builder.setModule(module);
+                   }
+                   BRACEOPEN ModuleStatements_opt BRACECLOSE
+                 | MODULE ModuleName
+                   {
+                     builder.setModule(new ModuleDef($2));
+                   }
+                   BRACEOPEN ModuleStatements_opt BRACECLOSE
+                 ;
+
+//  ModuleName:
+//    Identifier
+//    ModuleName . Identifier
+ModuleName: QualifiedIdentifier 
+          ;
+ModuleNameList: ModuleName {
+                  moduleTargets.add($1);
+                }
+              | ModuleNameList COMMA ModuleName {
+                  moduleTargets.add($3);
+                }
+              ;
+
+// ModuleStatement:
+//    requires {RequiresModifier} ModuleName ;
+//    exports PackageName [to ModuleName {, ModuleName}] ;
+//    opens PackageName [to ModuleName {, ModuleName}] ;
+//    uses TypeName ;
+//    provides TypeName with TypeName {, TypeName} ;
+ModuleStatement: REQUIRES RequiresModifiers_opt ModuleName SEMI 
+                 {
+                   ModuleDef.RequiresDef req = new ModuleDef.RequiresDef($3, modifiers);
+                   modifiers = new java.util.LinkedHashSet<String>();
+                   req.setLineNumber(line);
+                   builder.addRequires(req);
+                 }
+               | EXPORTS QualifiedIdentifier /* =PackageName */ 
+                 {
+                   exp = new ModuleDef.ExportsDef($2);
+                   exp.setLineNumber(line);
+                 } 
+                 ToDeclaration_opt SEMI
+                 {
+                   exp.getTargets().addAll(moduleTargets);
+                   moduleTargets = new LinkedList<String>();
+                   builder.addExports(exp);
+                 }
+               | OPENS QualifiedIdentifier /* =PackageName */
+                 {
+                   opn = new ModuleDef.OpensDef($2);
+                   opn.setLineNumber(line);
+                 }
+                 ToDeclaration_opt SEMI
+                 {
+                   opn.getTargets().addAll(moduleTargets);
+                   moduleTargets = new LinkedList<String>();
+                   builder.addOpens(opn);
+                 }
+               | USES Type /* =TypeName */ SEMI {
+                   ModuleDef.UsesDef uss = new ModuleDef.UsesDef($2);
+                   uss.setLineNumber(line);
+                   builder.addUses(uss);
+                 }
+               | PROVIDES Type /* =TypeName */ 
+                 {
+                   prv = new ModuleDef.ProvidesDef($2);
+                   prv.setLineNumber(line);
+                 }
+                 WITH TypeList SEMI 
+                 {
+                   prv.getImplementations().addAll(typeList);
+                   builder.addProvides(prv);
+                 }
+               ;
+ModuleStatements_opt: 
+                    | ModuleStatements_opt ModuleStatement
+                    ;
+
+RequiresModifier: TRANSITIVE { modifiers.add("transitive"); }
+                | STATIC     { modifiers.add("static"); }
+                ;
+RequiresModifiers_opt:
+                     | RequiresModifiers_opt RequiresModifier
+                     ;
+                     
+ToDeclaration_opt:
+                 | TO ModuleNameList
+                 ;
+
 // PackageDeclaration:
 //     {PackageModifier} package Identifier {. Identifier} ;
 // PackageModifier:
 //      Annotation   
-PackageDeclaration: package
-                  | Annotation
+PackageDeclaration: PACKAGE 
+                    { 
+                      line = lexer.getLine(); 
+                    } 
+                    QualifiedIdentifier /* =PackageName */SEMI 
+                    { 
+                      builder.addPackage(new PackageDef($3, line)); 
+                    }
                   ;
-PackageDeclaration_opt:
-                      | PackageDeclaration_opt PackageDeclaration
-                      ;
-
-package: PACKAGE 
-         { 
-           line = lexer.getLine(); 
-         } 
-         QualifiedIdentifier /* =PackageName */SEMI 
-         { 
-           builder.addPackage(new PackageDef($3, line)); 
-         }
-         ;
 
 // ImportDeclaration:
 //     SingleTypeImportDeclaration 
@@ -109,9 +207,6 @@ ImportDeclaration: SingleTypeImportDeclaration
                  | SingleStaticImportDeclaration
                  | StaticImportOnDemandDeclaration
                  ;
-ImportDeclarations_opt: 
-                      | ImportDeclarations_opt ImportDeclaration
-                      ;
 
 // SingleTypeImportDeclaration:
 //     import TypeName ; 
@@ -153,13 +248,6 @@ TypeDeclaration: ClassDeclaration
                | InterfaceDeclaration
                | SEMI
                ;
-TypeDeclarations_opt: 
-                    | TypeDeclarations_opt 
-                      { 
-                        line = lexer.getLine(); 
-                      } 
-                      TypeDeclaration
-                    ;
 
 // -----------------------------
 // Productions from �8 (Classes)
@@ -174,12 +262,15 @@ ClassDeclaration: NormalClassDeclaration
 
 // NormalClassDeclaration: 
 //     {ClassModifier} class Identifier [TypeParameters] [Superclass] [Superinterfaces] ClassBody
-NormalClassDeclaration: Modifiers_opt CLASS IDENTIFIER TypeParameters_opt Superclass_opt Superinterfaces_opt  
+NormalClassDeclaration: Modifiers_opt CLASS IDENTIFIER
                         {
                           cls.setType(ClassDef.CLASS);
-                          cls.setLineNumber(line);
+                          cls.setLineNumber(lexer.getLine());
                           cls.getModifiers().addAll(modifiers); modifiers.clear(); 
                           cls.setName( $3 );
+                        }
+                        TypeParameters_opt Superclass_opt Superinterfaces_opt  
+                        {
                           cls.setTypeParameters(typeParams);
                           builder.beginClass(cls); 
                           cls = new ClassDef(); 
@@ -338,11 +429,24 @@ MethodHeader: TypeParameters Type /* =Result */ IDENTIFIER
                 mth.setTypeParams(typeParams);
                 mth.setReturnType($2);
                 mth.setName($3);
-              } 
+              }
               PARENOPEN FormalParameterList_opt PARENCLOSE Dims_opt Throws_opt
               {
                 mth.setDimensions($8);
-              } 
+              }
+            | TypeParameters Annotation Type /* =Result */ IDENTIFIER
+              {
+                builder.beginMethod();
+                mth.setLineNumber(lexer.getLine());
+                mth.getModifiers().addAll(modifiers); modifiers.clear();
+                mth.setTypeParams(typeParams);
+                mth.setReturnType($3);
+                mth.setName($4);
+              }
+              PARENOPEN FormalParameterList_opt PARENCLOSE Dims_opt Throws_opt
+              {
+                mth.setDimensions($9);
+              }
             | Type /* =Result */ IDENTIFIER  
               {
                 builder.beginMethod();
@@ -811,11 +915,12 @@ PrimaryNoNewArray: Literal
                    {
                      $$ = new TypeRefDef(new TypeDef($1, $2));
                    } 
+                 | MethodInvocation
+                 | MethodReference 
                  | QualifiedIdentifier 
                    { 
                      $$ = new FieldRefDef($1); 
                    }
-                 | MethodInvocation 
                  ;
 
 // ClassInstanceCreationExpression:
@@ -823,13 +928,13 @@ PrimaryNoNewArray: Literal
 //     ExpressionName . new [TypeArguments] {Annotation} Identifier [TypeArgumentsOrDiamond] ( [ArgumentList] ) [ClassBody] 
 //     Primary . new [TypeArguments] {Annotation} Identifier [TypeArgumentsOrDiamond] ( [ArgumentList] ) [ClassBody]
 //// TypeArguments_opt confuses parser
-ClassInstanceCreationExpression: NEW TypeArguments_opt IDENTIFIER TypeArgumentsOrDiamond_opt PARENOPEN ArgumentList_opt PARENCLOSE ClassBody_opt 
+ClassInstanceCreationExpression: NEW TypeArguments IDENTIFIER TypeArgumentsOrDiamond_opt PARENOPEN ArgumentList_opt PARENCLOSE CODEBLOCK_opt 
                                  { 
                                    CreatorDef creator = new CreatorDef();
                                    creator.setCreatedName( $3 );
                                    $$ = creator; 
                                  }
-                               | NEW IDENTIFIER TypeArgumentsOrDiamond_opt PARENOPEN ArgumentList_opt PARENCLOSE ClassBody_opt
+                               | NEW IDENTIFIER TypeArgumentsOrDiamond_opt PARENOPEN ArgumentList_opt PARENCLOSE CODEBLOCK_opt
                                  {
                                    CreatorDef creator = new CreatorDef();
                                    creator.setCreatedName( $2 );
@@ -837,6 +942,10 @@ ClassInstanceCreationExpression: NEW TypeArguments_opt IDENTIFIER TypeArgumentsO
                                  }
                                ;
 
+CODEBLOCK_opt:
+             | CODEBLOCK
+             ;
+
 // TypeArgumentsOrDiamond:
 //     TypeArguments 
 //     <>
@@ -866,17 +975,21 @@ MethodInvocation: IDENTIFIER PARENOPEN ArgumentList_opt PARENCLOSE
                   {
                     $$ = new MethodInvocationDef($1, null);
                   }
-                | SUPER DOT TypeParameters_opt IDENTIFIER PARENOPEN ArgumentList_opt PARENCLOSE
+                | QualifiedIdentifier PARENOPEN ArgumentList_opt PARENCLOSE
                   {
                     $$ = new MethodInvocationDef($1, null);
                   }
-                | QualifiedIdentifier DOT SUPER DOT TypeParameters_opt IDENTIFIER PARENOPEN ArgumentList_opt PARENCLOSE
+                | QualifiedIdentifier DOT TypeParameters IDENTIFIER PARENOPEN ArgumentList_opt PARENCLOSE
                   {
-                    $$ = new MethodInvocationDef($1 + ".super", null);
+                    $$ = new MethodInvocationDef($1, null);
                   }
-                | QualifiedIdentifier DOT TypeParameters_opt IDENTIFIER PARENOPEN ArgumentList_opt PARENCLOSE
+                | SUPER DOT TypeParameters_opt IDENTIFIER PARENOPEN ArgumentList_opt PARENCLOSE
                   {
-                    $$ = new MethodInvocationDef($1, null);
+                    $$ = new MethodInvocationDef("super." + $1, null);
+                  }
+                | QualifiedIdentifier DOT SUPER DOT TypeParameters_opt IDENTIFIER PARENOPEN ArgumentList_opt PARENCLOSE
+                  {
+                    $$ = new MethodInvocationDef($1 + ".super", null);
                   }
                 ;
 
@@ -903,6 +1016,23 @@ ArgumentList_opt:
 //     TypeName . super :: [TypeArguments] Identifier 
 //     ClassType :: [TypeArguments] new 
 //     ArrayType :: new
+MethodReference: QualifiedIdentifier COLONCOLON TypeArguments_opt IDENTIFIER
+                 {
+                   $$ = new MethodReferenceDef();
+                 }
+               | SUPER COLONCOLON TypeArguments_opt IDENTIFIER
+                 {
+                   $$ = new MethodReferenceDef();
+                 }
+               | QualifiedIdentifier COLONCOLON NEW
+                 {
+                   $$ = new MethodReferenceDef();
+                 }
+               | ArrayType COLONCOLON TypeArguments_opt IDENTIFIER
+                 {
+                   $$ = new MethodReferenceDef();
+                 }
+               ;
 
 // ArrayCreationExpression:
 //     new PrimitiveType DimExprs [Dims] 
@@ -1664,6 +1794,10 @@ private StringBuilder textBuffer = new StringBuilder();
 private ClassDef cls = new ClassDef();
 private MethodDef mth = new MethodDef();
 private FieldDef fd;
+private ModuleDef.ExportsDef exp;
+private ModuleDef.OpensDef opn;
+private ModuleDef.ProvidesDef prv;
+private List<String> moduleTargets = new LinkedList<String>();
 private List<TypeVariableDef> typeParams = new LinkedList<TypeVariableDef>(); //for both JavaClass and JavaMethod
 private LinkedList<AnnoDef> annotationStack = new LinkedList<AnnoDef>(); // Use LinkedList instead of Stack because it is unsynchronized 
 private List<List<ElemValueDef>> annoValueListStack = new LinkedList<List<ElemValueDef>>(); // Use LinkedList instead of Stack because it is unsynchronized
diff --git a/src/it/lambda-examples/verify.groovy b/src/it/lambda-examples/verify.groovy
index 25e6fe5..355ddb6 100644
--- a/src/it/lambda-examples/verify.groovy
+++ b/src/it/lambda-examples/verify.groovy
@@ -1,8 +1,8 @@
 def buildLog = new File( basedir, "build.log" )
 
-// zip contains 6 java files + empty LambdaExamples01/nbproject/private/config.properties 
-assert buildLog.text.contains( "Success: 7" )
-// zip contains 9 non-java files
-assert buildLog.text.contains( "Failure: 9" )
+// zip contains 6 java files
+assert buildLog.text.contains( "Success: 6" )
+// zip contains 10 non-java files 
+assert buildLog.text.contains( "Failure: 10" )
 assert buildLog.text.contains( "Error  : 0" )
 assert buildLog.text.contains( "Total  : 16" )
diff --git a/src/main/java/com/thoughtworks/qdox/JavaProjectBuilder.java b/src/main/java/com/thoughtworks/qdox/JavaProjectBuilder.java
index 72b9ce6..d736499 100644
--- a/src/main/java/com/thoughtworks/qdox/JavaProjectBuilder.java
+++ b/src/main/java/com/thoughtworks/qdox/JavaProjectBuilder.java
@@ -37,6 +37,7 @@ import com.thoughtworks.qdox.library.ClassLibraryBuilder;
 import com.thoughtworks.qdox.library.ErrorHandler;
 import com.thoughtworks.qdox.library.SortedClassLibraryBuilder;
 import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaModule;
 import com.thoughtworks.qdox.model.JavaPackage;
 import com.thoughtworks.qdox.model.JavaSource;
 
@@ -178,12 +179,13 @@ public class JavaProjectBuilder
      * JavaClass is called it will be searched by matching the package with the folder structure and the classname with
      * the filename
      * 
-     * @see #addSourceTree(File)
      * @param sourceFolder the sourcefolder to add
+     * @return the {@link JavaModule} when the sourceFolder has a module-info, otherwise {@code null}
+     * @see #addSourceTree(File)
      */
-    public void addSourceFolder( File sourceFolder )
+    public JavaModule addSourceFolder( File sourceFolder )
     {
-        classLibraryBuilder.appendSourceFolder( sourceFolder );
+        return classLibraryBuilder.addSourceFolder( sourceFolder );
     }
 
     /**
@@ -305,6 +307,11 @@ public class JavaProjectBuilder
         return classLibraryBuilder.getClassLibrary().getJavaPackages();
     }
 
+    public Collection<JavaModule> getModules()
+    {
+        return classLibraryBuilder.getClassLibrary().getJavaModules();
+    }
+    
     // Searcher
 
     public Collection<JavaClass> search( Searcher searcher )
@@ -345,6 +352,10 @@ public class JavaProjectBuilder
 
     /**
      * Note that after loading JavaDocBuilder classloaders need to be re-added.
+     * 
+     * @param file the file to load
+     * @return the deserialized project builder
+     * @throws IOException when file could not be deserialized
      */
     public static JavaProjectBuilder load( File file )
         throws IOException
diff --git a/src/main/java/com/thoughtworks/qdox/builder/Builder.java b/src/main/java/com/thoughtworks/qdox/builder/Builder.java
index e843baa..8d3b0ca 100644
--- a/src/main/java/com/thoughtworks/qdox/builder/Builder.java
+++ b/src/main/java/com/thoughtworks/qdox/builder/Builder.java
@@ -21,6 +21,7 @@ package com.thoughtworks.qdox.builder;
 
 import java.net.URL;
 
+import com.thoughtworks.qdox.model.JavaModule;
 import com.thoughtworks.qdox.model.JavaSource;
 import com.thoughtworks.qdox.parser.expression.ExpressionDef;
 import com.thoughtworks.qdox.parser.structs.AnnoDef;
@@ -28,6 +29,7 @@ import com.thoughtworks.qdox.parser.structs.ClassDef;
 import com.thoughtworks.qdox.parser.structs.FieldDef;
 import com.thoughtworks.qdox.parser.structs.InitDef;
 import com.thoughtworks.qdox.parser.structs.MethodDef;
+import com.thoughtworks.qdox.parser.structs.ModuleDef;
 import com.thoughtworks.qdox.parser.structs.PackageDef;
 import com.thoughtworks.qdox.parser.structs.TagDef;
 import com.thoughtworks.qdox.writer.ModelWriterFactory;
@@ -37,6 +39,14 @@ public interface Builder
     void setModelWriterFactory( ModelWriterFactory writer );
     
     void setUrl( URL url );
+    
+    void setModule( ModuleDef moduleDef );
+    
+    void addExports( ModuleDef.ExportsDef exports );
+    void addRequires( ModuleDef.RequiresDef requires );
+    void addOpens( ModuleDef.OpensDef opens );
+    void addProvides( ModuleDef.ProvidesDef provides );
+    void addUses( ModuleDef.UsesDef uses );
 
     void addPackage( PackageDef packageDef );
 
@@ -66,4 +76,6 @@ public interface Builder
     void addArgument(  ExpressionDef argument );
 
     JavaSource getSource();
+
+    JavaModule getModuleInfo();
 }
\ No newline at end of file
diff --git a/src/main/java/com/thoughtworks/qdox/builder/TypeAssembler.java b/src/main/java/com/thoughtworks/qdox/builder/TypeAssembler.java
index 04ec986..353251c 100644
--- a/src/main/java/com/thoughtworks/qdox/builder/TypeAssembler.java
+++ b/src/main/java/com/thoughtworks/qdox/builder/TypeAssembler.java
@@ -26,10 +26,10 @@ import com.thoughtworks.qdox.model.JavaType;
 import com.thoughtworks.qdox.model.impl.DefaultJavaParameterizedType;
 import com.thoughtworks.qdox.model.impl.DefaultJavaWildcardType;
 import com.thoughtworks.qdox.model.impl.DefaultJavaWildcardType.BoundType;
-import com.thoughtworks.qdox.model.impl.JavaClassParent;
 import com.thoughtworks.qdox.model.impl.DefaultJavaType;
 import com.thoughtworks.qdox.parser.structs.TypeDef;
 import com.thoughtworks.qdox.parser.structs.WildcardTypeDef;
+import com.thoughtworks.qdox.type.TypeResolver;
 
 /**
  * An assembler to transform a {@link TypeDef} to a {@link DefaultJavaType}
@@ -47,12 +47,12 @@ public final class TypeAssembler
      * this one is specific for those cases where dimensions can be part of both the type and identifier i.e. private
      * String[] matrix[]; //field public abstract String[] getMatrix[](); //method
      * 
-     * @param typeDef
-     * @param dimensions
-     * @param context
+     * @param typeDef the type definition
+     * @param dimensions the array-depth
+     * @param typeResolver the typeResolver
      * @return the Type
      */
-    public static DefaultJavaType createUnresolved( TypeDef typeDef, int dimensions, JavaClassParent context )
+    public static DefaultJavaType createUnresolved( TypeDef typeDef, int dimensions, TypeResolver typeResolver)
     {
         DefaultJavaType result;
         if ( typeDef instanceof WildcardTypeDef )
@@ -60,7 +60,7 @@ public final class TypeAssembler
             WildcardTypeDef wildcard = (WildcardTypeDef) typeDef;
             if( wildcard.getTypeDef() != null )
             {
-                JavaType type = createUnresolved( wildcard.getTypeDef(), context );
+                JavaType type = createUnresolved( wildcard.getTypeDef(), typeResolver );
                 DefaultJavaWildcardType.BoundType boundType = null;
                 if( "extends".equals( wildcard.getWildcardExpressionType() ) )
                 {
@@ -79,13 +79,14 @@ public final class TypeAssembler
         }
         else
         {
-            DefaultJavaParameterizedType typeResult = new DefaultJavaParameterizedType( null, typeDef.getName(), typeDef.getDimensions() + dimensions, context );
+            DefaultJavaParameterizedType typeResult = new DefaultJavaParameterizedType( null, typeDef.getName(), typeDef.getDimensions() + dimensions, typeResolver );
+            
             if ( typeDef.getActualArgumentTypes() != null && !typeDef.getActualArgumentTypes().isEmpty() )
             {
                 List<JavaType> actualArgumentTypes = new LinkedList<JavaType>();
                 for ( TypeDef actualArgType : typeDef.getActualArgumentTypes() )
                 {
-                    actualArgumentTypes.add( TypeAssembler.createUnresolved( actualArgType, context ) );
+                    actualArgumentTypes.add( TypeAssembler.createUnresolved( actualArgType, typeResolver ) );
                 }
                 typeResult.setActualArgumentTypes( actualArgumentTypes );
             }
@@ -95,13 +96,13 @@ public final class TypeAssembler
     }
 
     /**
-     * @param typeDef the TypeDef
-     * @param context the context
+     * @param typeDef the type definition
+     * @param typeResolver the typeResolver
      * @return the Type
      */
-    public static DefaultJavaType createUnresolved( TypeDef typeDef, JavaClassParent context )
+    public static DefaultJavaType createUnresolved( TypeDef typeDef, TypeResolver typeResolver )
     {
-        return createUnresolved( typeDef, 0, context );
+        return createUnresolved( typeDef, 0, typeResolver );
     }
 
 }
diff --git a/src/main/java/com/thoughtworks/qdox/builder/impl/DefaultJavaAnnotationAssembler.java b/src/main/java/com/thoughtworks/qdox/builder/impl/DefaultJavaAnnotationAssembler.java
index 32490b8..16a0fdf 100644
--- a/src/main/java/com/thoughtworks/qdox/builder/impl/DefaultJavaAnnotationAssembler.java
+++ b/src/main/java/com/thoughtworks/qdox/builder/impl/DefaultJavaAnnotationAssembler.java
@@ -24,7 +24,7 @@ import java.util.List;
 import java.util.Map;
 
 import com.thoughtworks.qdox.builder.TypeAssembler;
-import com.thoughtworks.qdox.model.JavaAnnotatedElement;
+import com.thoughtworks.qdox.library.ClassLibrary;
 import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaType;
 import com.thoughtworks.qdox.model.expression.Add;
@@ -64,7 +64,6 @@ import com.thoughtworks.qdox.model.expression.ShiftRight;
 import com.thoughtworks.qdox.model.expression.Subtract;
 import com.thoughtworks.qdox.model.expression.TypeRef;
 import com.thoughtworks.qdox.model.expression.UnsignedShiftRight;
-import com.thoughtworks.qdox.model.impl.AbstractBaseJavaEntity;
 import com.thoughtworks.qdox.model.impl.DefaultJavaAnnotation;
 import com.thoughtworks.qdox.parser.expression.AddDef;
 import com.thoughtworks.qdox.parser.expression.AndDef;
@@ -87,6 +86,7 @@ import com.thoughtworks.qdox.parser.expression.LogicalAndDef;
 import com.thoughtworks.qdox.parser.expression.LogicalNotDef;
 import com.thoughtworks.qdox.parser.expression.LogicalOrDef;
 import com.thoughtworks.qdox.parser.expression.MethodInvocationDef;
+import com.thoughtworks.qdox.parser.expression.MethodReferenceDef;
 import com.thoughtworks.qdox.parser.expression.MinusSignDef;
 import com.thoughtworks.qdox.parser.expression.MultiplyDef;
 import com.thoughtworks.qdox.parser.expression.NotDef;
@@ -107,26 +107,32 @@ import com.thoughtworks.qdox.parser.expression.TypeRefDef;
 import com.thoughtworks.qdox.parser.expression.UnsignedShiftRightDef;
 import com.thoughtworks.qdox.parser.structs.AnnoDef;
 import com.thoughtworks.qdox.parser.structs.TypeDef;
+import com.thoughtworks.qdox.type.TypeResolver;
 
 public class DefaultJavaAnnotationAssembler
     implements ElemValueTransformer<AnnotationValue>
 {
+    private JavaClass declaringClass;
+    
+    private ClassLibrary classLibrary;
+    
+    private TypeResolver typeResolver;
 
-    private AbstractBaseJavaEntity parent;
-
-    public DefaultJavaAnnotationAssembler( JavaAnnotatedElement parent )
+    public DefaultJavaAnnotationAssembler( JavaClass declaringClass, ClassLibrary classLibrary, TypeResolver typeResolver )
     {
-        this.parent = (AbstractBaseJavaEntity) parent;
+        this.declaringClass = declaringClass;
+        this.classLibrary = classLibrary;
+        this.typeResolver = typeResolver;
     }
 
     public DefaultJavaAnnotation assemble( AnnoDef annoDef ) {
-        DefaultJavaAnnotation annotation =
-            new DefaultJavaAnnotation( createType( annoDef.getTypeDef(), 0 ), annoDef.getLineNumber() );
+        DefaultJavaAnnotation annotation = new DefaultJavaAnnotation( createType( annoDef.getTypeDef(), 0 ) );
+        annotation.setLineNumber( annoDef.getLineNumber() );
+        
         for ( Map.Entry<String, ElemValueDef> annoVal : annoDef.getArgs().entrySet() )
         {
             annotation.setProperty( annoVal.getKey(), annoVal.getValue().transform( this ) );
         }
-        annotation.setContext( (JavaAnnotatedElement) parent );
         return annotation;
     }
     
@@ -144,8 +150,7 @@ public class DefaultJavaAnnotationAssembler
         }
         return TypeAssembler.createUnresolved( typeDef,
                                                dimensions,
-                                               parent.getParentClass() != null ? parent.getParentClass()
-                                                               : parent.getSource() );
+                                               typeResolver  );
     }
     
     /** {@inheritDoc} */
@@ -364,7 +369,8 @@ public class DefaultJavaAnnotationAssembler
         FieldRef result;
         String name = annotationFieldRef.getName();
         result = new FieldRef( name );
-        result.setContext( (JavaAnnotatedElement) parent );
+        result.setDeclaringClass( declaringClass );
+        result.setClassLibrary( classLibrary );
         return result;
     }
 
@@ -452,6 +458,10 @@ public class DefaultJavaAnnotationAssembler
         return null;
     }
 
+    public AnnotationValue transform( MethodReferenceDef methodReferenceDef )
+    {
+        return null;
+    }
     public AnnotationValue transform( CreatorDef newCreator )
     {
         return null;
diff --git a/src/main/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitor.java b/src/main/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitor.java
index 51d7a44..36dc7a4 100644
--- a/src/main/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitor.java
+++ b/src/main/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitor.java
@@ -115,8 +115,10 @@ public class EvaluatingVisitor
      * <p>
      * Performs binary numeric promotion as specified in the Java Language Specification,
      * 
-     * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#170983">section
-     *      5.6.1<a>
+     * @param left the left hand side instance
+     * @param right the right hand side instance
+     * @return the expected result Class 
+     * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#170983">section 5.6.1</a>
      */
     protected static Class<?> resultType( final Object left, final Object right )
     {
@@ -154,8 +156,10 @@ public class EvaluatingVisitor
      * <p>
      * Performs binary numeric promotion as specified in the Java Language Specification,
      * 
-     * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#170983">section
-     *      5.6.1<a>
+     * @param left the left hand side instance
+     * @param right the right hand side instance
+     * @return the expected result Class 
+     * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#170983">section 5.6.1</a>
      */
     protected static Class<?> numericResultType( final Object left, final Object right )
     {
@@ -181,8 +185,9 @@ public class EvaluatingVisitor
      * <p>
      * Performs unary numeric promotion as specified in the Java Language Specification,
      * 
-     * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#170952">section
-     *      5.6.2<a>
+     * @param value the instance
+     * @return the expected result Class 
+     * @see <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#170952">section 5.6.2</a>
      */
     protected static Class<?> unaryNumericResultType( final Object value )
     {
@@ -219,11 +224,13 @@ public class EvaluatingVisitor
         return type;
     }
 
+    /** {@inheritDoc} */
     public Object visit( JavaAnnotation annotation ) throws UnsupportedOperationException
     {
         throw new UnsupportedOperationException( "Illegal annotation value '" + annotation + "'." );
     }
 
+    /** {@inheritDoc} */
     public Object visit( Add op )
     {
         Object left = op.getLeft().accept( this );
@@ -260,11 +267,13 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( Constant constant )
     {
         return constant.getValue();
     }
 
+    /** {@inheritDoc} */
     public Object visit( Divide op )
     {
         Object left = op.getLeft().accept( this );
@@ -296,6 +305,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( FieldRef fieldRef )
     {
         JavaField javaField = fieldRef.getField();
@@ -317,6 +327,7 @@ public class EvaluatingVisitor
         throw new UnsupportedOperationException("getFieldReferenceValue(JavaField) has not been implemented.");
     }
 
+    /** {@inheritDoc} */
     public Object visit( GreaterThan op )
     {
         Object left = op.getLeft().accept( this );
@@ -348,6 +359,7 @@ public class EvaluatingVisitor
         return result ? Boolean.TRUE : Boolean.FALSE;
     }
 
+    /** {@inheritDoc} */
     public Object visit( LessThan op )
     {
         Object left = op.getLeft().accept( this );
@@ -379,6 +391,7 @@ public class EvaluatingVisitor
         return result ? Boolean.TRUE : Boolean.FALSE;
     }
 
+    /** {@inheritDoc} */
     public Object visit( Multiply op )
     {
         Object left = op.getLeft().accept( this );
@@ -410,11 +423,13 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( ParenExpression parenExpression )
     {
         return parenExpression.getValue().accept( this );
     }
 
+    /** {@inheritDoc} */
     public Object visit( Subtract op )
     {
         Object left = op.getLeft().accept( this );
@@ -446,11 +461,13 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public JavaType visit( TypeRef typeRef )
     {
         return typeRef.getType();
     }
 
+    /** {@inheritDoc} */
     public List<?> visit( AnnotationValueList valueList )
     {
         List<Object> list = new LinkedList<Object>();
@@ -464,6 +481,7 @@ public class EvaluatingVisitor
         return list;
     }
 
+    /** {@inheritDoc} */
     public Object visit( And and )
     {
         Object left = and.getLeft().accept( this );
@@ -487,6 +505,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( GreaterEquals greaterEquals )
     {
         Object left = greaterEquals.getLeft().accept( this );
@@ -518,6 +537,7 @@ public class EvaluatingVisitor
         return result ? Boolean.TRUE : Boolean.FALSE;
     }
 
+    /** {@inheritDoc} */
     public Object visit( LessEquals lessEquals )
     {
         Object left = lessEquals.getLeft().accept( this );
@@ -549,6 +569,7 @@ public class EvaluatingVisitor
         return result ? Boolean.TRUE : Boolean.FALSE;
     }
 
+    /** {@inheritDoc} */
     public Object visit( LogicalAnd and )
     {
         Object left = and.getLeft().accept( this );
@@ -567,6 +588,7 @@ public class EvaluatingVisitor
         return result ? Boolean.TRUE : Boolean.FALSE;
     }
 
+    /** {@inheritDoc} */
     public Object visit( LogicalNot not )
     {
         Object value = not.getValue().accept( this );
@@ -584,6 +606,7 @@ public class EvaluatingVisitor
         return result ? Boolean.TRUE : Boolean.FALSE;
     }
 
+    /** {@inheritDoc} */
     public Object visit( LogicalOr or )
     {
         Object left = or.getLeft().accept( this );
@@ -602,6 +625,7 @@ public class EvaluatingVisitor
         return result ? Boolean.TRUE : Boolean.FALSE;
     }
 
+    /** {@inheritDoc} */
     public Object visit( MinusSign sign )
     {
         Object value = sign.getValue().accept( this );
@@ -632,6 +656,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( Not not )
     {
         Object value = not.getValue().accept( this );
@@ -654,6 +679,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( Or or )
     {
         Object left = or.getLeft().accept( this );
@@ -677,6 +703,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( PlusSign sign )
     {
         Object value = sign.getValue().accept( this );
@@ -694,6 +721,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( Remainder remainder )
     {
         Object left = remainder.getLeft().accept( this );
@@ -725,6 +753,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( ShiftLeft shiftLeft )
     {
         Object left = shiftLeft.getLeft().accept( this );
@@ -748,6 +777,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( ShiftRight shiftRight )
     {
         Object left = shiftRight.getLeft().accept( this );
@@ -771,6 +801,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( UnsignedShiftRight shiftRight )
     {
         Object left = shiftRight.getLeft().accept( this );
@@ -794,6 +825,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( Equals annotationEquals )
     {
         Object left = annotationEquals.getLeft().accept( this );
@@ -825,6 +857,7 @@ public class EvaluatingVisitor
         return result ? Boolean.TRUE : Boolean.FALSE;
     }
 
+    /** {@inheritDoc} */
     public Object visit( ExclusiveOr annotationExclusiveOr )
     {
         Object left = annotationExclusiveOr.getLeft().accept( this );
@@ -848,6 +881,7 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( NotEquals annotationNotEquals )
     {
         Object left = annotationNotEquals.getLeft().accept( this );
@@ -879,6 +913,7 @@ public class EvaluatingVisitor
         return result ? Boolean.TRUE : Boolean.FALSE;
     }
 
+    /** {@inheritDoc} */
     public Object visit( Query annotationQuery )
     {
         Object value = annotationQuery.getCondition().accept( this );
@@ -895,6 +930,7 @@ public class EvaluatingVisitor
         return expression.accept( this );
     }
 
+    /** {@inheritDoc} */
     public Object visit( Cast annotationCast )
     {
         Object value = annotationCast.getValue().accept( this );
@@ -954,31 +990,37 @@ public class EvaluatingVisitor
         return result;
     }
 
+    /** {@inheritDoc} */
     public Object visit( PreDecrement preDecrement )
     {
         throw new IllegalArgumentException( "Cannot evaluate '" + preDecrement + "'." );
     }
-    
+
+    /** {@inheritDoc} */
     public Object visit( PreIncrement preIncrement )
     {
         throw new IllegalArgumentException( "Cannot evaluate '" + preIncrement + "'." );
     }
-    
+
+    /** {@inheritDoc} */
     public Object visit( PostDecrement postDecrement )
     {
         throw new IllegalArgumentException( "Cannot evaluate '" + postDecrement + "'." );
     }
-    
+
+    /** {@inheritDoc} */
     public Object visit( PostIncrement postIncrement )
     {
         throw new IllegalArgumentException( "Cannot evaluate '" + postIncrement + "'." );
     }
 
+    /** {@inheritDoc} */
     public Object visit( Assignment assignment )
     {
         throw new IllegalArgumentException( "Cannot evaluate '" + assignment + "'." );
     }
-    
+
+    /** {@inheritDoc} */
     public Object visit( MethodInvocation methodInvocation )
     {
         throw new IllegalArgumentException( "Cannot evaluate '" + methodInvocation + "'." );
diff --git a/src/main/java/com/thoughtworks/qdox/builder/impl/ModelBuilder.java b/src/main/java/com/thoughtworks/qdox/builder/impl/ModelBuilder.java
index 7570486..9980cba 100644
--- a/src/main/java/com/thoughtworks/qdox/builder/impl/ModelBuilder.java
+++ b/src/main/java/com/thoughtworks/qdox/builder/impl/ModelBuilder.java
@@ -34,8 +34,10 @@ import com.thoughtworks.qdox.model.JavaAnnotatedElement;
 import com.thoughtworks.qdox.model.JavaAnnotation;
 import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaConstructor;
+import com.thoughtworks.qdox.model.JavaExecutable;
 import com.thoughtworks.qdox.model.JavaGenericDeclaration;
 import com.thoughtworks.qdox.model.JavaMethod;
+import com.thoughtworks.qdox.model.JavaModule;
 import com.thoughtworks.qdox.model.JavaParameter;
 import com.thoughtworks.qdox.model.JavaSource;
 import com.thoughtworks.qdox.model.JavaType;
@@ -47,6 +49,13 @@ import com.thoughtworks.qdox.model.impl.DefaultJavaConstructor;
 import com.thoughtworks.qdox.model.impl.DefaultJavaField;
 import com.thoughtworks.qdox.model.impl.DefaultJavaInitializer;
 import com.thoughtworks.qdox.model.impl.DefaultJavaMethod;
+import com.thoughtworks.qdox.model.impl.DefaultJavaModule;
+import com.thoughtworks.qdox.model.impl.DefaultJavaModuleDescriptor;
+import com.thoughtworks.qdox.model.impl.DefaultJavaModuleDescriptor.DefaultJavaExports;
+import com.thoughtworks.qdox.model.impl.DefaultJavaModuleDescriptor.DefaultJavaOpens;
+import com.thoughtworks.qdox.model.impl.DefaultJavaModuleDescriptor.DefaultJavaProvides;
+import com.thoughtworks.qdox.model.impl.DefaultJavaModuleDescriptor.DefaultJavaRequires;
+import com.thoughtworks.qdox.model.impl.DefaultJavaModuleDescriptor.DefaultJavaUses;
 import com.thoughtworks.qdox.model.impl.DefaultJavaPackage;
 import com.thoughtworks.qdox.model.impl.DefaultJavaParameter;
 import com.thoughtworks.qdox.model.impl.DefaultJavaSource;
@@ -58,10 +67,17 @@ import com.thoughtworks.qdox.parser.structs.ClassDef;
 import com.thoughtworks.qdox.parser.structs.FieldDef;
 import com.thoughtworks.qdox.parser.structs.InitDef;
 import com.thoughtworks.qdox.parser.structs.MethodDef;
+import com.thoughtworks.qdox.parser.structs.ModuleDef;
+import com.thoughtworks.qdox.parser.structs.ModuleDef.ExportsDef;
+import com.thoughtworks.qdox.parser.structs.ModuleDef.OpensDef;
+import com.thoughtworks.qdox.parser.structs.ModuleDef.ProvidesDef;
+import com.thoughtworks.qdox.parser.structs.ModuleDef.RequiresDef;
+import com.thoughtworks.qdox.parser.structs.ModuleDef.UsesDef;
 import com.thoughtworks.qdox.parser.structs.PackageDef;
 import com.thoughtworks.qdox.parser.structs.TagDef;
 import com.thoughtworks.qdox.parser.structs.TypeDef;
 import com.thoughtworks.qdox.parser.structs.TypeVariableDef;
+import com.thoughtworks.qdox.type.TypeResolver;
 import com.thoughtworks.qdox.writer.ModelWriterFactory;
 
 /**
@@ -71,6 +87,10 @@ import com.thoughtworks.qdox.writer.ModelWriterFactory;
 public class ModelBuilder implements Builder {
 
     private final DefaultJavaSource source;
+    
+    private DefaultJavaModule module;
+    
+    private DefaultJavaModuleDescriptor moduleDescriptor;
 
     private LinkedList<DefaultJavaClass> classStack = new LinkedList<DefaultJavaClass>();
 
@@ -90,12 +110,15 @@ public class ModelBuilder implements Builder {
 
     private List<TagDef> lastTagSet = new LinkedList<TagDef>();
 
+    private ClassLibrary classLibrary;
+    
     private DocletTagFactory docletTagFactory;
 
     private ModelWriterFactory modelWriterFactory;
 
     public ModelBuilder( ClassLibrary classLibrary, DocletTagFactory docletTagFactory )
     {
+        this.classLibrary = classLibrary;
         this.docletTagFactory = docletTagFactory;
         this.source = new DefaultJavaSource( classLibrary );
         this.currentAnnoDefs = new LinkedList<AnnoDef>();
@@ -108,12 +131,88 @@ public class ModelBuilder implements Builder {
         this.modelWriterFactory = modelWriterFactory;
         source.setModelWriterFactory( modelWriterFactory );
     }
+    
+    /** {@inheritDoc} */
+    public void setModule( final ModuleDef moduleDef )
+    {
+        this.moduleDescriptor = new DefaultJavaModuleDescriptor(moduleDef.getName());
+        this.module = new DefaultJavaModule(moduleDef.getName(), moduleDescriptor);
+    }
+    
+    /** {@inheritDoc} */
+    public void addExports( ExportsDef exportsDef )
+    {
+        // for now use anonymous modules
+        List<JavaModule> targets = new ArrayList<JavaModule>(exportsDef.getTargets().size());
+        for ( String moduleName : exportsDef.getTargets() )
+        {
+            targets.add( new DefaultJavaModule( moduleName, null ) );
+        }
+        
+        DefaultJavaExports exports =
+            new DefaultJavaExports( new DefaultJavaPackage(exportsDef.getSource()), targets );
+        exports.setLineNumber( exportsDef.getLineNumber() );
+        exports.setModelWriterFactory( modelWriterFactory );
+        moduleDescriptor.addExports( exports );
+    }
+    
+    /** {@inheritDoc} */
+    public void addOpens( OpensDef opensDef )
+    {
+     // for now use anonymous modules
+        List<JavaModule> targets = new ArrayList<JavaModule>(opensDef.getTargets().size());
+        for ( String moduleName : opensDef.getTargets() )
+        {
+            targets.add( new DefaultJavaModule( moduleName, null ) );
+        }
+        
+        DefaultJavaOpens exports =
+            new DefaultJavaOpens( new DefaultJavaPackage(opensDef.getSource()), targets );
+        exports.setLineNumber( opensDef.getLineNumber() );
+        exports.setModelWriterFactory( modelWriterFactory );
+        moduleDescriptor.addOpens( exports );
+    }
+
+    /** {@inheritDoc} */
+    public void addProvides( ProvidesDef providesDef )
+    {
+        JavaClass service = createType( providesDef.getService(), 0 );
+        List<JavaClass> implementations = new LinkedList<JavaClass>();
+        for ( TypeDef implementType : providesDef.getImplementations() )
+        {
+            implementations.add( createType( implementType, 0 ) );
+        }
+        DefaultJavaProvides provides = new DefaultJavaProvides( service, implementations );
+        provides.setLineNumber( providesDef.getLineNumber() );
+        provides.setModelWriterFactory( modelWriterFactory );
+        moduleDescriptor.addProvides( provides );
+    }
+
+    /** {@inheritDoc} */
+    public void addRequires( RequiresDef requiresDef )
+    {
+        JavaModule module = new DefaultJavaModule( requiresDef.getName(), null );
+        DefaultJavaRequires requires = new DefaultJavaRequires( module, requiresDef.getModifiers() );
+        requires.setLineNumber( requiresDef.getLineNumber() );
+        requires.setModelWriterFactory( modelWriterFactory );
+        moduleDescriptor.addRequires( requires );
+    }
+
+    /** {@inheritDoc} */
+    public void addUses( UsesDef usesDef )
+    {
+        DefaultJavaUses uses = new DefaultJavaUses( createType( usesDef.getService(), 0 ) );
+        uses.setLineNumber( usesDef.getLineNumber() );
+        uses.setModelWriterFactory( modelWriterFactory );
+        moduleDescriptor.addUses( uses );
+    }
+    
 
     /** {@inheritDoc} */
     public void addPackage( PackageDef packageDef )
     {
         DefaultJavaPackage jPackage = new DefaultJavaPackage( packageDef.getName() );
-        jPackage.setClassLibrary( source.getJavaClassLibrary() );
+        jPackage.setClassLibrary( classLibrary );
         jPackage.setLineNumber( packageDef.getLineNumber() );
         jPackage.setModelWriterFactory( modelWriterFactory );
         addJavaDoc( jPackage );
@@ -211,7 +310,7 @@ public class ModelBuilder implements Builder {
         else if ( !classStack.isEmpty() )
         {
             classStack.getFirst().addClass( newClass );
-            newClass.setParentClass( classStack.getFirst() );
+            newClass.setDeclaringClass( classStack.getFirst() );
         }
         else
         {
@@ -241,8 +340,17 @@ public class ModelBuilder implements Builder {
         {
             return null;
         }
-        return TypeAssembler.createUnresolved( typeDef, dimensions,
-                                               classStack.isEmpty() ? source : classStack.getFirst() );
+        TypeResolver typeResolver;
+        if(classStack.isEmpty())
+        {
+            typeResolver = TypeResolver.byPackageName( source.getPackageName(), classLibrary, source.getImports() );
+        }
+        else
+        {
+            typeResolver = TypeResolver.byClassName( classStack.getFirst().getBinaryName(), classLibrary, source.getImports() );
+        }
+        
+        return TypeAssembler.createUnresolved( typeDef, dimensions, typeResolver );
     }
 
     private void addJavaDoc( AbstractBaseJavaEntity entity )
@@ -260,6 +368,7 @@ public class ModelBuilder implements Builder {
         lastComment = null;
     }
     
+    /** {@inheritDoc} */
     public void addInitializer( InitDef def )
     {
         DefaultJavaInitializer initializer = new DefaultJavaInitializer();
@@ -277,7 +386,7 @@ public class ModelBuilder implements Builder {
     {
         currentConstructor = new DefaultJavaConstructor();
 
-        currentConstructor.setParentClass( classStack.getFirst() );
+        currentConstructor.setDeclaringClass( classStack.getFirst() );
 
         currentConstructor.setModelWriterFactory( modelWriterFactory );
 
@@ -333,7 +442,7 @@ public class ModelBuilder implements Builder {
         currentMethod = new DefaultJavaMethod();
         if ( currentField == null )
         {
-            currentMethod.setParentClass( classStack.getFirst() );
+            currentMethod.setDeclaringClass( classStack.getFirst() );
             classStack.getFirst().addMethod( currentMethod );
         }
         currentMethod.setModelWriterFactory( modelWriterFactory );
@@ -390,7 +499,10 @@ public class ModelBuilder implements Builder {
         {
             return null;
         }
-        DefaultJavaTypeVariable<G> result = new DefaultJavaTypeVariable<G>( typeVariableDef.getName(), genericDeclaration );
+        JavaClass declaringClass = getContext( genericDeclaration );
+        TypeResolver typeResolver = TypeResolver.byClassName( declaringClass.getBinaryName(), classLibrary, source.getImports() );
+        
+        DefaultJavaTypeVariable<G> result = new DefaultJavaTypeVariable<G>( typeVariableDef.getName(), typeResolver );
 
         if ( typeVariableDef.getBounds() != null && !typeVariableDef.getBounds().isEmpty() )
         {
@@ -403,16 +515,33 @@ public class ModelBuilder implements Builder {
         }
         return result;
     }
+    
+    private static JavaClass getContext( JavaGenericDeclaration genericDeclaration )
+    {
+        JavaClass result;
+        if ( genericDeclaration instanceof JavaClass )
+        {
+            result = (JavaClass) genericDeclaration;
+        }
+        else if ( genericDeclaration instanceof JavaExecutable )
+        {
+            result = ( (JavaExecutable) genericDeclaration ).getDeclaringClass();
+        }
+        else
+        {
+            throw new IllegalArgumentException( "Unknown JavaGenericDeclaration implementation" );
+        }
+        return result;
+    }
 
     /** {@inheritDoc} */
     public void beginField( FieldDef def )
     {
-        currentField = new DefaultJavaField();
-        currentField.setParentClass( classStack.getFirst() );
+        currentField = new DefaultJavaField( def.getName() );
+        currentField.setDeclaringClass( classStack.getFirst() );
         currentField.setLineNumber( def.getLineNumber() );
         currentField.setModelWriterFactory( modelWriterFactory );
 
-        currentField.setName( def.getName() );
         currentField.setType( createType( def.getType(), def.getDimensions() ) );
         
         currentField.setEnumConstant( def.isEnumConstant() );
@@ -437,8 +566,18 @@ public class ModelBuilder implements Builder {
 	{
 	    if ( currentArguments != null && !currentArguments.isEmpty() )
         {
+	        TypeResolver typeResolver;
+	        if( classStack.isEmpty() )
+	        {
+	            typeResolver = TypeResolver.byPackageName( source.getPackageName(), classLibrary, source.getImports() );
+	        }
+	        else
+	        {
+	            typeResolver = TypeResolver.byClassName( classStack.getFirst().getBinaryName(), classLibrary, source.getImports() );
+	        }
+	        
 	        //DefaultExpressionTransformer?? 
-            DefaultJavaAnnotationAssembler assembler = new DefaultJavaAnnotationAssembler( currentField );
+            DefaultJavaAnnotationAssembler assembler = new DefaultJavaAnnotationAssembler( currentField.getDeclaringClass(), classLibrary, typeResolver );
 
             List<Expression> arguments = new LinkedList<Expression>();
             for ( ExpressionDef annoDef : currentArguments )
@@ -462,11 +601,11 @@ public class ModelBuilder implements Builder {
                                       fieldDef.isVarArgs() );
         if( currentMethod != null )
         {
-            jParam.setDeclarator( currentMethod );
+            jParam.setExecutable( currentMethod );
         }
         else
         {
-            jParam.setDeclarator( currentConstructor );
+            jParam.setExecutable( currentConstructor );
         }
         jParam.setModelWriterFactory( modelWriterFactory );
         addJavaDoc( jParam );
@@ -478,7 +617,17 @@ public class ModelBuilder implements Builder {
     {
         if ( !currentAnnoDefs.isEmpty() )
         {
-            DefaultJavaAnnotationAssembler assembler = new DefaultJavaAnnotationAssembler( (JavaAnnotatedElement) entity );
+            TypeResolver typeResolver;
+            if( classStack.isEmpty() )
+            {
+                typeResolver = TypeResolver.byPackageName( source.getPackageName(), classLibrary, source.getImports() );
+            }
+            else
+            {
+                typeResolver = TypeResolver.byClassName( classStack.getFirst().getBinaryName(), classLibrary, source.getImports() );
+            }
+            
+            DefaultJavaAnnotationAssembler assembler = new DefaultJavaAnnotationAssembler( entity.getDeclaringClass(), classLibrary, typeResolver );
 
             List<JavaAnnotation> annotations = new LinkedList<JavaAnnotation>();
             for ( AnnoDef annoDef : currentAnnoDefs )
@@ -497,16 +646,25 @@ public class ModelBuilder implements Builder {
         currentAnnoDefs.add( annotation );
     }
     
+    /** {@inheritDoc} */
     public void addArgument( ExpressionDef argument )
     {
         currentArguments.add( argument );
     }
 
+    /** {@inheritDoc} */
     public JavaSource getSource()
     {
         return source;
     }
+    
+    /** {@inheritDoc} */
+    public JavaModule getModuleInfo()
+    {
+        return module;
+    }
 
+    /** {@inheritDoc} */
     public void setUrl( URL url )
     {
         source.setURL( url );
diff --git a/src/main/java/com/thoughtworks/qdox/library/AbstractClassLibrary.java b/src/main/java/com/thoughtworks/qdox/library/AbstractClassLibrary.java
index f488a1f..45b6737 100644
--- a/src/main/java/com/thoughtworks/qdox/library/AbstractClassLibrary.java
+++ b/src/main/java/com/thoughtworks/qdox/library/AbstractClassLibrary.java
@@ -29,6 +29,7 @@ import com.thoughtworks.qdox.builder.Builder;
 import com.thoughtworks.qdox.builder.ModelBuilderFactory;
 import com.thoughtworks.qdox.builder.impl.ModelBuilder;
 import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaModule;
 import com.thoughtworks.qdox.model.JavaPackage;
 import com.thoughtworks.qdox.model.JavaSource;
 import com.thoughtworks.qdox.model.impl.DefaultDocletTagFactory;
@@ -65,17 +66,28 @@ public abstract class AbstractClassLibrary
 
     /**
      * constructor for chained ClassLibrary
+     * @param parent the parent library
      */
     public AbstractClassLibrary( AbstractClassLibrary parent )
     {
         this.parentClassLibrary = parent;
     }
+    
+    public Collection<JavaModule> getJavaModules()
+    {
+        Collection<JavaModule> modules = null;
+        if ( parentClassLibrary != null )
+        {
+            modules = parentClassLibrary.getJavaModules();
+        }
+        return modules;
+    }
 
     /**
      * First checks if there's a JavaClass available in the private context by this name. Otherwise try to resolve it by
      * the concrete class. If there's still no JavaClass, ask the parent (if available) to resolve it.
      * 
-     * @param name
+     * @param name the binary name of the class
      * @return the JavaClass matching the name, otherwise <code>null</code>
      */
     public final JavaClass getJavaClass( String name ) {
@@ -140,7 +152,7 @@ public abstract class AbstractClassLibrary
     /**
      * 
      * 
-     * @param filter
+     * @param filter the classlibrary filter
      * @return JavaSources matching the filter
      */
     protected final Collection<JavaSource> getJavaSources( ClassLibraryFilter filter) {
@@ -157,8 +169,8 @@ public abstract class AbstractClassLibrary
     /**
      * Get all the classes of the current {@link AbstractClassLibrary}.
      * Subclasses can overwrite this method by including the following code
-     * <code> 
-     * public List<JavaClass> getClasses()
+     * <pre> 
+     * public List<JavaClass> getClasses()
      * {
      *   return getJavaClasses( new ClassLibraryFilter()
      *   {
@@ -168,7 +180,7 @@ public abstract class AbstractClassLibrary
      *      }
      *   });
      * }
-     * </code>
+     * </pre>
      * This example would return all created {@link JavaClass } objects, including those from the classloaders.
      * 
      * @return all JavaClasses of this ClassLibrary
@@ -181,7 +193,7 @@ public abstract class AbstractClassLibrary
     /**
      * Subclasses can call this method to gather all JavaClass object, including those from the parent.
      * 
-     * @param filter
+     * @param filter the classlibrary filter
      * @return JavaClasses matching the filter
      */
     protected final Collection<JavaClass> getJavaClasses( ClassLibraryFilter filter) {
@@ -198,8 +210,8 @@ public abstract class AbstractClassLibrary
     /**
      * Get all packages of the current {@link AbstractClassLibrary}.
      * Subclasses can overwrite this method by including the following code
-     * <code> 
-     * public List<JavaPackage> getJavaPackages()
+     * <pre> 
+     * public List<JavaPackage> getJavaPackages()
      * {
      *   return getJavaPackages( new ClassLibraryFilter()
      *   {
@@ -209,7 +221,7 @@ public abstract class AbstractClassLibrary
      *      }
      *   });
      * }
-     * </code>
+     * </pre>
      * This example would return all created {@link JavaPackage } objects, including those from the classloaders.
      * 
      * @return all JavaPackages of this ClassLibrary
diff --git a/src/main/java/com/thoughtworks/qdox/library/ClassLibrary.java b/src/main/java/com/thoughtworks/qdox/library/ClassLibrary.java
index f9750bb..f8e63a2 100644
--- a/src/main/java/com/thoughtworks/qdox/library/ClassLibrary.java
+++ b/src/main/java/com/thoughtworks/qdox/library/ClassLibrary.java
@@ -23,6 +23,7 @@ import java.io.Serializable;
 import java.util.Collection;
 
 import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaModule;
 import com.thoughtworks.qdox.model.JavaPackage;
 import com.thoughtworks.qdox.model.JavaSource;
 
@@ -38,7 +39,7 @@ public interface ClassLibrary
     /**
      * Check if this library holds a reference based on the name.
      * 
-     * @param name the Fully Qualified Name trying to resolve
+     * @param name the (binary) name trying to resolve
      * @return true if the classLibrary has a reference, otherwise <code>false</code>
      */
     boolean hasClassReference( String name );
@@ -46,16 +47,16 @@ public interface ClassLibrary
     /**
      * Get the JavaClass or null if it's not possible
      * 
-     * @param name The fully qualified name of the JavaClass
+     * @param name The (binary) name of the JavaClass
      * @return the JavaClass, otherwise <code>null</code>
      */
     JavaClass getJavaClass( String name );
 
     /**
-     * Try to retrieve the JavaClass by a fully qualified name.
+     * Try to retrieve the JavaClass by the (binary) name.
      * If the JavaClss doesn't exist and createStub is <code>true</code> make a stub, otherwise return <code>null</code>
      * 
-     * @param name the fully qualified name of the class
+     * @param name the name of the class
      * @param createStub force creation of a stub if the class can't be found
      * @return the JavaClass, might be <code>null</code> depending on the value of createStub. 
      */
@@ -93,4 +94,6 @@ public interface ClassLibrary
      * @return all JavaPackages as a List, never <code>null</code>
      */
     Collection<JavaPackage> getJavaPackages();
+
+    Collection<JavaModule> getJavaModules();
 }
diff --git a/src/main/java/com/thoughtworks/qdox/library/ClassLibraryBuilder.java b/src/main/java/com/thoughtworks/qdox/library/ClassLibraryBuilder.java
index 0f9ca8f..94ad547 100644
--- a/src/main/java/com/thoughtworks/qdox/library/ClassLibraryBuilder.java
+++ b/src/main/java/com/thoughtworks/qdox/library/ClassLibraryBuilder.java
@@ -27,6 +27,7 @@ import java.io.Serializable;
 import java.net.URL;
 
 import com.thoughtworks.qdox.builder.ModelBuilderFactory;
+import com.thoughtworks.qdox.model.JavaModule;
 import com.thoughtworks.qdox.model.JavaSource;
 import com.thoughtworks.qdox.writer.ModelWriterFactory;
 
@@ -58,14 +59,14 @@ public interface ClassLibraryBuilder extends Serializable
 
     /**
      * 
-     * @param sourceFolder
+     * @param sourceFolder the source folder
      * @return this ClassLibraryBuilder instance
      */
     ClassLibraryBuilder appendSourceFolder( File sourceFolder );
 
     /**
      * 
-     * @param stream
+     * @param stream the Java source as stream
      * @return this ClassLibraryBuilder instance
      * @throws IOException if an IOException is thrown, e.g. unsupported encoding
      */
@@ -73,30 +74,30 @@ public interface ClassLibraryBuilder extends Serializable
 
     /**
      * 
-     * @param reader
+     * @param reader the Java source as reader
      * @return this ClassLibraryBuilder instance
      */
     ClassLibraryBuilder appendSource( Reader reader );
 
     /**
      * 
-     * @param url
+     * @param url the Java source as URL
      * @return this ClassLibraryBuilder instance
-     * @throws IOException
+     * @throws IOException if an IOException occurs
      */
     ClassLibraryBuilder appendSource( URL url ) throws IOException;
 
     /**
      * 
-     * @param file
+     * @param file the Java source as file
      * @return this ClassLibraryBuilder instance
-     * @throws IOException
+     * @throws IOException if an IOException occurs
      */
     ClassLibraryBuilder appendSource( File file ) throws IOException;
 
     /**
      * 
-     * @param stream
+     * @param stream the Java source as stream
      * @return the created JavaSource
      * @throws IOException if an IOException is thrown, e.g. unsupported encoding
      */
@@ -105,44 +106,46 @@ public interface ClassLibraryBuilder extends Serializable
     /**
      * Add the source content of the reader to the ClassLibrary and return the generated JavaSource
      * 
-     * @param reader
+     * @param reader the Java source as reader
      * @return the created JavaSource
      */
     JavaSource addSource( Reader reader );
     
     /**
      * 
-     * @param url
+     * @param url the Java source as URL
      * @return the created JavaSource
-     * @throws IOException
+     * @throws IOException if an IOException occurs
      */
     JavaSource addSource( URL url ) throws IOException;
     
     /**
      * 
-     * @param file
+     * @param file the Java source as file
      * @return the created JavaSource
-     * @throws IOException
+     * @throws IOException if an IOException occurs
      */
     JavaSource addSource( File file ) throws IOException;
     
     /**
+     * Set to {@code true} to enable debug logging for the lexer
      * 
-     * @param debugLexer
+     * @param debugLexer the debug logging flag
      * @return this ClassLibraryBuilder instance
      */
     ClassLibraryBuilder setDebugLexer( boolean debugLexer );
 
     /**
+     * Set to {@code true} to enable debug logging for the parser
      * 
-     * @param debugParser
+     * @param debugParser the debug logging flag
      * @return this ClassLibraryBuilder instance
      */
     ClassLibraryBuilder setDebugParser( boolean debugParser );
     
     /**
      * 
-     * @param encoding
+     * @param encoding set the encoding
      * @return this ClassLibraryBuilder instance
      */
     ClassLibraryBuilder setEncoding( String encoding );
@@ -179,4 +182,12 @@ public interface ClassLibraryBuilder extends Serializable
      */
     ClassLibraryBuilder setErrorHander( ErrorHandler errorHandler );
 
+    /**
+     * 
+     * @param sourceFolder the sourcefolder
+     * @return the module info if the sourcefolder has a module-info.java, otherwise {@code null} 
+     * @since 2.0
+     */
+    JavaModule addSourceFolder( File sourceFolder );
+
 }
\ No newline at end of file
diff --git a/src/main/java/com/thoughtworks/qdox/library/ClassLoaderLibrary.java b/src/main/java/com/thoughtworks/qdox/library/ClassLoaderLibrary.java
index 3f030fb..7c1eda5 100644
--- a/src/main/java/com/thoughtworks/qdox/library/ClassLoaderLibrary.java
+++ b/src/main/java/com/thoughtworks/qdox/library/ClassLoaderLibrary.java
@@ -27,7 +27,6 @@ import java.util.LinkedList;
 import java.util.List;
 
 import com.thoughtworks.qdox.builder.Builder;
-import com.thoughtworks.qdox.builder.impl.ModelBuilder;
 import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaPackage;
 import com.thoughtworks.qdox.model.impl.DefaultJavaPackage;
@@ -40,14 +39,14 @@ import com.thoughtworks.qdox.parser.impl.Parser;
 /**
  * <strong>Important!! Be sure to add a classloader with the bootstrap classes.</strong>
  * <p>
- * Normally you can generate your classLibrary like this:<br/>
+ * Normally you can generate your classLibrary like this:<br>
  * <code>
  *  ClassLibrary classLibrary = new ClassLibrary();
  *  classLibrary.addDefaultLoader();
  * </code>
  * </p>
  * <p>
- * If you want full control over the classLoaders you might want to create your library like:<br/>
+ * If you want full control over the classLoaders you might want to create your library like:<br>
  * <code>
  * ClassLibrary classLibrary = new ClassLibrary( ClassLoader.getSystemClassLoader() )
  * </code>
@@ -206,9 +205,9 @@ public class ClassLoaderLibrary
     }
     
     /**
-     * Use the Lexer in debug mode
+     * Set to {@code true} to enable debug logging for the lexer
      * 
-     * @param debugLexer 
+     * @param debugLexer the debug logging flag
      */
     public void setDebugLexer( boolean debugLexer )
     {
@@ -216,9 +215,9 @@ public class ClassLoaderLibrary
     }
     
     /**
-     * Use the Parser in debug mode
+     * Set to {@code true} to enable debug logging for the parser
      * 
-     * @param debugParser
+     * @param debugParser the debug logging flag
      */
     public void setDebugParser( boolean debugParser )
     {
diff --git a/src/main/java/com/thoughtworks/qdox/library/ClassNameLibrary.java b/src/main/java/com/thoughtworks/qdox/library/ClassNameLibrary.java
index b3a6776..d5fac29 100644
--- a/src/main/java/com/thoughtworks/qdox/library/ClassNameLibrary.java
+++ b/src/main/java/com/thoughtworks/qdox/library/ClassNameLibrary.java
@@ -39,10 +39,18 @@ public class ClassNameLibrary
     protected JavaClass resolveJavaClass( String name )
     {
         Builder unknownBuilder = getModelBuilder();
-        unknownBuilder.beginClass( new ClassDef( name ) );
-        unknownBuilder.endClass();
+        
+        String[] names = name.split( "\\$" ); 
+        for(int i=0;i<names.length;i++)
+        {
+            unknownBuilder.beginClass( new ClassDef( names[i] ) );
+        }
+        for(int i=0;i<names.length;i++)
+        {
+            unknownBuilder.endClass();
+        }
         JavaSource unknownSource = unknownBuilder.getSource();
-        return unknownSource.getClasses().get( 0 );
+        return unknownSource.getClassByName( name );
     }
     
     @Override
diff --git a/src/main/java/com/thoughtworks/qdox/library/JavaClassContext.java b/src/main/java/com/thoughtworks/qdox/library/JavaClassContext.java
index 6cc3563..8d72e9f 100644
--- a/src/main/java/com/thoughtworks/qdox/library/JavaClassContext.java
+++ b/src/main/java/com/thoughtworks/qdox/library/JavaClassContext.java
@@ -87,7 +87,7 @@ public class JavaClassContext implements Serializable {
 	 * @param javaClass the JavaClass to add
 	 */
 	public void add(JavaClass javaClass) {
-	    classMap.put(javaClass.getFullyQualifiedName(), javaClass);
+	    classMap.put(javaClass.getBinaryName(), javaClass);
 	}
 	
 	/**
diff --git a/src/main/java/com/thoughtworks/qdox/library/OrderedClassLibraryBuilder.java b/src/main/java/com/thoughtworks/qdox/library/OrderedClassLibraryBuilder.java
index bb16c5d..e654a5b 100644
--- a/src/main/java/com/thoughtworks/qdox/library/OrderedClassLibraryBuilder.java
+++ b/src/main/java/com/thoughtworks/qdox/library/OrderedClassLibraryBuilder.java
@@ -26,6 +26,7 @@ import java.io.Reader;
 import java.net.URL;
 
 import com.thoughtworks.qdox.builder.ModelBuilderFactory;
+import com.thoughtworks.qdox.model.JavaModule;
 import com.thoughtworks.qdox.model.JavaSource;
 import com.thoughtworks.qdox.writer.ModelWriterFactory;
 
@@ -66,7 +67,7 @@ public class OrderedClassLibraryBuilder implements ClassLibraryBuilder
      * Constructor for which you can set the root ClassLibrary
      * If you set this to null, all classes should be available on the classpath.
      * 
-     * @param rootClassLibrary
+     * @param rootClassLibrary the parent Classlibrary
      */
     public OrderedClassLibraryBuilder( AbstractClassLibrary rootClassLibrary )
     {
@@ -275,6 +276,12 @@ public class OrderedClassLibraryBuilder implements ClassLibraryBuilder
         return sourceLibrary.addSource( file );
     }
     
+    public JavaModule addSourceFolder( File sourceFolder )
+    {
+        SourceFolderLibrary sourceFolderLibrary = getSourceFolderLibrary();
+        return sourceFolderLibrary.addSourceFolder( sourceFolder );
+    }
+
     private void prepareSourceLibrary( SourceLibrary sourceLibrary ) {
         sourceLibrary.setModelBuilderFactory( modelBuilderFactory );
         sourceLibrary.setModelWriterFactory( modelWriterFactory );
@@ -294,6 +301,17 @@ public class OrderedClassLibraryBuilder implements ClassLibraryBuilder
         return sourceLibrary;
     }
     
+    private SourceFolderLibrary getSourceFolderLibrary()
+    {
+        if ( !( classLibrary instanceof SourceFolderLibrary ) )
+        {
+            classLibrary = newSourceFolderLibrary( classLibrary );
+        }
+        SourceFolderLibrary library = (SourceFolderLibrary) classLibrary;
+        prepareSourceLibrary( library );
+        return library;
+    }
+    
     /**
      * Ability to override the implementation of ClassLoaderLibrary
      * 
diff --git a/src/main/java/com/thoughtworks/qdox/library/SortedClassLibraryBuilder.java b/src/main/java/com/thoughtworks/qdox/library/SortedClassLibraryBuilder.java
index 9d3d755..a0da973 100644
--- a/src/main/java/com/thoughtworks/qdox/library/SortedClassLibraryBuilder.java
+++ b/src/main/java/com/thoughtworks/qdox/library/SortedClassLibraryBuilder.java
@@ -26,6 +26,7 @@ import java.io.Reader;
 import java.net.URL;
 
 import com.thoughtworks.qdox.builder.ModelBuilderFactory;
+import com.thoughtworks.qdox.model.JavaModule;
 import com.thoughtworks.qdox.model.JavaSource;
 import com.thoughtworks.qdox.writer.ModelWriterFactory;
 
@@ -173,4 +174,8 @@ public class SortedClassLibraryBuilder
         return sourceLibrary.addSource( file );
     }
 
+    public JavaModule addSourceFolder( File sourceFolder )
+    {
+        return sourceFolderLibrary.addSourceFolder( sourceFolder );
+    }
 }
diff --git a/src/main/java/com/thoughtworks/qdox/library/SourceFolderLibrary.java b/src/main/java/com/thoughtworks/qdox/library/SourceFolderLibrary.java
index f2d3cec..ae7e8dc 100644
--- a/src/main/java/com/thoughtworks/qdox/library/SourceFolderLibrary.java
+++ b/src/main/java/com/thoughtworks/qdox/library/SourceFolderLibrary.java
@@ -23,11 +23,14 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 
 import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaModule;
 import com.thoughtworks.qdox.model.JavaSource;
 
 /**
@@ -51,25 +54,69 @@ public class SourceFolderLibrary
         this.sourceFolders.add( sourceFolder );
     }
 
-    public void addSourceFolder( File sourceFolder )
+    public JavaModule addSourceFolder( File sourceFolder )
     {
         this.sourceFolders.add( sourceFolder );
+        return resolveJavaModule( sourceFolder );
+    }
+
+    @Override
+    public Collection<JavaModule> getJavaModules()
+    {
+        return resolveJavaModules();
+    }
+    
+    private Collection<JavaModule> resolveJavaModules()
+    {
+        Collection<JavaModule> modules = new ArrayList<JavaModule>(sourceFolders.size());
+        for ( File sourceFolder : sourceFolders )
+        {
+            JavaModule module = resolveJavaModule( sourceFolder );
+            if( module != null)
+            {
+                modules.add( module );
+            }
+        }
+        return modules;
+    }
+    
+    private JavaModule resolveJavaModule( File sourceFolder )
+    {
+        JavaModule result = null;
+        File moduleInfoFile = new File( sourceFolder, "module-info.java" );
+        if ( moduleInfoFile.isFile()  )
+        {
+            try
+            {
+                result = parse( new FileReader( moduleInfoFile ), moduleInfoFile.toURI().toURL() ).getModuleInfo();
+            }
+            catch ( FileNotFoundException e )
+            {
+                // noop
+            }
+            catch ( MalformedURLException e )
+            {
+               // noop
+            }
+        }
+        return result;
     }
 
     @Override
     protected JavaClass resolveJavaClass( String className )
     {
-        JavaClass result = null;
+        JavaClass result = super.resolveJavaClass( className );
         for ( File sourceFolder : sourceFolders )
         {
             String mainClassName = className.split( "\\$" )[0];
             File classFile = new File( sourceFolder, mainClassName.replace( '.', File.separatorChar ) + ".java" );
-            if ( classFile.exists() && classFile.isFile() )
+            if ( classFile.isFile() )
             {
                 try
                 {
-                    JavaSource source = parse( new FileReader( classFile ), classFile.toURI().toURL() );
+                    JavaSource source = parse( new FileReader( classFile ), classFile.toURI().toURL() ).getSource();
                     result = source.getClassByName( className );
+                    break;
                 }
                 catch ( FileNotFoundException e )
                 {
@@ -90,7 +137,7 @@ public class SourceFolderLibrary
     @Override
     protected boolean containsClassReference( String className )
     {
-        boolean result = false;
+        boolean result = super.containsClassReference( className );
         for ( Iterator<File> iterator = sourceFolders.iterator(); !result && iterator.hasNext(); )
         {
             File sourceFolder = (File) iterator.next();
diff --git a/src/main/java/com/thoughtworks/qdox/library/SourceLibrary.java b/src/main/java/com/thoughtworks/qdox/library/SourceLibrary.java
index 8869e5f..f0eb2a2 100644
--- a/src/main/java/com/thoughtworks/qdox/library/SourceLibrary.java
+++ b/src/main/java/com/thoughtworks/qdox/library/SourceLibrary.java
@@ -69,7 +69,7 @@ public class SourceLibrary
     /**
      * Create a new instance of SourceLibrary and chain it to the parent 
      * 
-     * @param parent
+     * @param parent the parent classLibrary
      */
     public SourceLibrary( AbstractClassLibrary parent )
     {
@@ -91,8 +91,13 @@ public class SourceLibrary
     
     private JavaSource addSource( Reader reader, URL url )
     {
-        JavaSource source = parse( reader, url );
-        registerJavaSource(source);
+        Builder builder = parse( reader, url );
+        JavaSource source = null;
+        if( builder != null )
+        {
+            source = builder.getSource();
+            registerJavaSource(source);
+        }
         return source;
     }
 
@@ -102,12 +107,18 @@ public class SourceLibrary
      * @param stream an {@link InputStream} which should contain java code
      * @return The constructed {@link JavaSource} object of this stream
      * @throws ParseException if this content couldn't be parsed to a JavaModel
+     * @throws IOException  if an IOException occurs
      */
     public JavaSource addSource( InputStream stream )
         throws ParseException, IOException
     {
-        JavaSource source = parse( stream, null );
-        registerJavaSource(source);
+        Builder builder = parse( stream, null );
+        JavaSource source = null;
+        if( builder != null)
+        {
+            source=  builder.getSource();
+            registerJavaSource(source);
+        }
         return source;
     }
     
@@ -117,6 +128,7 @@ public class SourceLibrary
      * @param url a {@link URL} which should contain java code
      * @return The constructed {@link JavaSource} object of this url
      * @throws ParseException if this content couldn't be parsed to a JavaModel
+     * @throws IOException  if an IOException occurs
      */
     public JavaSource addSource( URL url )
         throws ParseException, IOException
@@ -129,8 +141,8 @@ public class SourceLibrary
      * 
      * @param file a {@link File} which should contain java code
      * @return The constructed {@link JavaSource} object of this file
-     * @throws ParseException
-     * @throws IOException
+     * @throws ParseException if this content couldn't be parsed to a JavaModel
+     * @throws IOException  if an IOException occurs
      */
     public JavaSource addSource( File file )
         throws ParseException, IOException
@@ -138,7 +150,19 @@ public class SourceLibrary
         JavaSource result = null;
         if ( !"package-info.java".equals( file.getName() ) ) 
         {
-            result = parse( new FileInputStream( file ), file.toURI().toURL() );
+            if ( "module-info.java".equals( file.getName() ) )
+            {
+                // No parse specifications yet
+                return result;
+            }
+
+            Builder builder = parse( new FileInputStream( file ), file.toURI().toURL() );
+            
+            if ( builder != null )
+            {
+                result = builder.getSource();
+            }
+            
             // if an error is handled by the errorHandler the result will be null
             if( result != null )
             {
@@ -147,7 +171,8 @@ public class SourceLibrary
                     File packageInfo = new File(file.getParentFile(), "package-info.java");
                     if( packageInfo.exists() )
                     {
-                        JavaPackage pckg = parse( new FileInputStream( packageInfo ), packageInfo.toURI().toURL() ).getPackage();
+                        JavaPackage pckg = parse( new FileInputStream( packageInfo ),
+                                                  packageInfo.toURI().toURL() ).getSource().getPackage();
                         context.add( pckg );
                     }
                 }
@@ -156,10 +181,8 @@ public class SourceLibrary
         }
     	return result;
     }
-    
-    
-    
-    protected JavaSource parse( Reader reader, URL url )
+
+    Builder parse( Reader reader, URL url )
         throws ParseException
     {
         try 
@@ -178,7 +201,7 @@ public class SourceLibrary
         }
     }
 
-    protected JavaSource parse( InputStream stream, URL url )
+    Builder parse( InputStream stream, URL url )
         throws ParseException, UnsupportedEncodingException
     {
         try 
@@ -197,10 +220,9 @@ public class SourceLibrary
         }
     }
 
-    private JavaSource parse( JavaLexer lexer, URL url )
+    private Builder parse( JavaLexer lexer, URL url )
         throws ParseException
     {
-        JavaSource result = null;
         Builder builder = getModelBuilder();
         builder.setUrl( url );
         Parser parser = new Parser( lexer, builder );
@@ -209,7 +231,7 @@ public class SourceLibrary
         try {
             if ( parser.parse() )
             {
-                result = builder.getSource();
+                return builder;
             }
         }
         catch( ParseException pe )
@@ -227,7 +249,7 @@ public class SourceLibrary
                 throw pe;
             }
         }
-        return result;
+        return null;
     }
 
     @Override
@@ -284,7 +306,7 @@ public class SourceLibrary
     /**
      * Use the Lexer in debug mode
      * 
-     * @param debugLexer 
+     * @param debugLexer the debug logging flag
      */
     public final void setDebugLexer( boolean debugLexer )
     {
@@ -299,7 +321,7 @@ public class SourceLibrary
     /**
      * Use the Parser in debug mode
      * 
-     * @param debugParser
+     * @param debugParser  the debug logging flag
      */
     public final void setDebugParser( boolean debugParser )
     {
@@ -314,7 +336,7 @@ public class SourceLibrary
     /**
      * Sets the encoding to use when parsing a URL or InputStreamReader
      * 
-     * @param encoding
+     * @param encoding the source encoding
      */
     public final void setEncoding( String encoding )
     {
diff --git a/src/main/java/com/thoughtworks/qdox/model/DocletTagFactory.java b/src/main/java/com/thoughtworks/qdox/model/DocletTagFactory.java
index e3d61ac..a91fd91 100644
--- a/src/main/java/com/thoughtworks/qdox/model/DocletTagFactory.java
+++ b/src/main/java/com/thoughtworks/qdox/model/DocletTagFactory.java
@@ -28,6 +28,12 @@ import java.io.Serializable;
 public interface DocletTagFactory extends Serializable {
 
     /**
+     * 
+     * @param tag the tag
+     * @param text the text
+     * @param context the context
+     * @param lineNumber the line number
+     * @return the doclet tag
      * @since 1.5
      */ 
     DocletTag createDocletTag(
@@ -35,6 +41,13 @@ public interface DocletTagFactory extends Serializable {
         JavaAnnotatedElement context, int lineNumber
     );
 
+    /**
+     * 
+     * @param tag the tag
+     * @param text the text
+     * @return the doclet tag
+     * @since 1.5
+     */ 
     DocletTag createDocletTag(String tag, String text);
 
 }
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaAnnotation.java b/src/main/java/com/thoughtworks/qdox/model/JavaAnnotation.java
index ace40b2..18ef4d2 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaAnnotation.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaAnnotation.java
@@ -23,7 +23,7 @@ import java.util.Map;
 
 import com.thoughtworks.qdox.model.expression.AnnotationValue;
 
-public interface JavaAnnotation {
+public interface JavaAnnotation extends JavaModel {
 
 	/**
 	 * @return the annotation type
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaClass.java b/src/main/java/com/thoughtworks/qdox/model/JavaClass.java
index e21fe53..df978c1 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaClass.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaClass.java
@@ -22,7 +22,6 @@ package com.thoughtworks.qdox.model;
 import java.util.List;
 
 import com.thoughtworks.qdox.library.ClassLibrary;
-import com.thoughtworks.qdox.model.impl.JavaClassParent;
 
 /**
  * Equivalent of {@link java.lang.Class}, providing the most important methods.
@@ -30,41 +29,14 @@ import com.thoughtworks.qdox.model.impl.JavaClassParent;
  * 
  * @author Robert Scholte
  */
-public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnnotatedElement, JavaGenericDeclaration
+public interface JavaClass extends JavaModel, JavaType, JavaAnnotatedElement, JavaGenericDeclaration
 {
-    
-    // deprecated methods
-    // will be removed with QDox-2.0
-    
     /**
-     * @deprecated the JavaClass should have the same methods
-     */
-    JavaType asType();
-
-    /**
-     * @deprecated Use {@link #getNestedClasses()} instead.
-     */
-    List<JavaClass> getClasses();
-
-    /**
-     * @deprecated use {@link #getNestedClassByName(String)} instead
-     */
-    JavaClass getInnerClassByName(String name);
-    
-    /**
-     * @deprecated use {@link #getNestedClasses()} instead
-     */
-    List<JavaClass> getInnerClasses();
-
-    /**
-     * @deprecated use {@link #getParentSource()} or {@link #getDeclaringClass()}
-     */
-    JavaClassParent getParent();
-
-    /**
-     * @deprecated use {@link #resolveCanonicalName(String)} or {@link #resolveFullyQualifiedName(String)} instead
+     * The compilation unit, which includes the imports, the public and anonymous classes
+     * 
+     * @return the {@link JavaSource} of this element
      */
-    String resolveType( String name );
+    JavaSource getSource();
 
     /**
      * (API description of {@link java.lang.Class#isInterface()})
@@ -104,19 +76,15 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
 
     /**
      * Shorthand for getSuperClass().getJavaClass() with null checking.
+     * @return the super class as {@link JavaClass}
      */
     JavaClass getSuperJavaClass();
 
     List<JavaType> getImplements();
 
     /**
-     * @since 1.3
-     */
-    List<JavaClass> getImplementedInterfaces();
-    
-    /**
      * Equivalent of {@link java.lang.Class#getInterfaces()}
-     *  Determines the interfaces implemented by the class or interface represented by this object.     * 
+     *  Determines the interfaces implemented by the class or interface represented by this object. 
      * 
      * @return a list of interfaces, never <code>null</code>
      * @since 2.0
@@ -129,7 +97,7 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
 
     /**
      * Equivalent of {@link java.lang.Class#getPackage()}
-     * @return
+     * @return the package
      */
     JavaPackage getPackage();
 
@@ -146,52 +114,6 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
      * @return <code>true</code> if this class is an inner class, otherwise <code>false</code>
      */
     boolean isInner();
-    
-    /**
-     * The name can be both absolute (including the package) or relative (matching a subclass or an import).
-     * 
-     * Tries to return the fully qualified name based on the name.
-     * The name tries to match the following:
-     * <ul>
-     *   <li>primitives or void</li>
-     *   <li>java.lang.*</li>
-     *   <li>inner classes</li>
-     *   <li>explicit imports</li>
-     *   <li>implicit imports</li>
-     * </ul> 
-     * 
-     * @param name the name to resolve
-     * @return the resolved canonical name, otherwise <code>null</code>
-     * @since 2.0
-     */
-    String resolveCanonicalName( String name );
-    
-    /**
-     * The name can be both absolute (including the package) or relative (matching a subclass or an import).
-     * 
-     * Tries to return the fully qualified name based on the name.
-     * The name tries to match the following:
-     * <ul>
-     *   <li>primitives or void</li>
-     *   <li>java.lang.*</li>
-     *   <li>inner classes</li>
-     *   <li>explicit imports</li>
-     *   <li>implicit imports</li>
-     * </ul> 
-     * 
-     * @param name the name to resolve
-     * @return the resolved fully qualified name, otherwise <code>null</code>
-     * @since 2.0
-     */
-    String resolveFullyQualifiedName( String name );
-
-    /**
-     * If this class has a package, it will return the package name, followed by a "."(dot).
-     * Otherwise it will return an empty String
-     * 
-     * @return the package name plus a dot if there's a package, otherwise an empty String
-     */
-    String getClassNamePrefix();
 
     /**
      * Equivalent of {@link java.lang.Class#getMethods()}
@@ -228,6 +150,10 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
     
 
     /**
+     * Return declared methods and optionally the inherited methods
+     *
+     * @param superclasses {@code true} if inherited methods should be returned as well 
+     * @return all methods
      * @since 1.3
      */
     List<JavaMethod> getMethods( boolean superclasses );
@@ -244,47 +170,47 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
      * This should be the signature for getMethodBySignature.
      * 
      * @param name the name of the method
-     * @param parameterTypes the parameter types of the method, can be <code>null<code>
+     * @param parameterTypes the parameter types of the method, can be {@code null}
      * @param varArgs define if the method has varArgs
-     * @return the matching method, otherwise <code>null</code>
+     * @return the matching method, otherwise  {@code null}
      */
     JavaMethod getMethod( String name, List<JavaType> parameterTypes, boolean varArgs );
 
     /**
      * 
      * @param name the name of the method
-     * @param parameterTypes the parameter types of the method, can be <code>null</code>
+     * @param parameterTypes the parameter types of the method, can be  {@code null}
      * @param superclasses to define if superclasses should be included as well
-     * @return the matching method, otherwise <code>null</code> 
+     * @return the matching method, otherwise  {@code null}
      */
     JavaMethod getMethodBySignature( String name, List<JavaType> parameterTypes, boolean superclasses );
 
     /**
      * 
      * @param name the name of the method
-     * @param parameterTypes the parameter types of the method, can be <code>null<code>
-     * @param superclasses
+     * @param parameterTypes the parameter types of the method, can be  {@code null}
+     * @param superclasses {@code true} if inherited methods should be matched as well
      * @param varArg define if the method has varArgs
-     * @return the matching method, otherwise <code>null</code>
+     * @return the matching method, otherwise  {@code null}
      */
     JavaMethod getMethodBySignature( String name, List<JavaType> parameterTypes, boolean superclasses, boolean varArg );
 
     /**
      * 
      * @param name the name of the method
-     * @param parameterTypes the parameter types of the method, can be <code>null<code>
-     * @param superclasses to define if superclasses should be included as well
-     * @return the matching methods, otherwise <code>null</code>
+     * @param parameterTypes the parameter types of the method, can be  {@code null}
+     * @param superclasses {@code true} if inherited methods should be matched as well
+     * @return the matching methods, otherwise  {@code null}
      */
     List<JavaMethod> getMethodsBySignature( String name, List<JavaType> parameterTypes, boolean superclasses );
 
     /**
      * 
      * @param name the name of the method
-     * @param parameterTypes the parameter types of the method, can be <code>null<code>
-     * @param superclasses to define if superclasses should be included as well
+     * @param parameterTypes the parameter types of the method, can be  {@code null}
+     * @param superclasses {@code true} if inherited methods should be matched as well
      * @param varArg define if the method has varArgs
-     * @return the matching methods, otherwise <code>null</code>
+     * @return the matching methods, otherwise  {@code null}
      */
     List<JavaMethod> getMethodsBySignature( String name, List<JavaType> parameterTypes, boolean superclasses,
                                                    boolean varArg );
@@ -292,15 +218,15 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
     /**
      * Equivalent of {@link java.lang.Class#getFields()}
      * 
-     * @return a list of fiels, never <code>null</code>
+     * @return a list of fiels, never  {@code null}
      */
     List<JavaField> getFields();
 
     /**
      * Equivalent of {@link java.lang.Class#getField(String)}, where this method can resolve every field
      * 
-     * @param name
-     * @return
+     * @param name the name of the field
+     * @return the field
      */
     JavaField getFieldByName( String name );
     
@@ -308,13 +234,13 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
      * Based on {@link java.lang.Class#getEnumConstants()}.
      *  
      * 
-     * @return a List of enum constants if this class is an <code>enum</code>, otherwise <code>null</code>
+     * @return a List of enum constants if this class is an <code>enum</code>, otherwise  {@code null}
      */
     List<JavaField> getEnumConstants();
 
     /**
      * 
-     * 
+     * @param name the name of the enum constant
      * @return the enumConstant matching the {@code name}, otherwise <code>null</code>
      */
     JavaField getEnumConstantByName( String name );
@@ -330,19 +256,23 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
     JavaClass getNestedClassByName( String name );
 
     /**
+     * @param fullyQualifiedName the FQN to match with
+     * @return {@code true} if this is of type FQN, otherwise {@code false}
      * @since 1.3
      */
     boolean isA( String fullyQualifiedName );
 
     /**
-     * @param javaClass 
+     * @param javaClass the JavaClass to match with
+     * @return {@code true} if this is of type {@literal javaClass}, otherwise {@code false}
      * @since 1.3
      */
     boolean isA( JavaClass javaClass );
 
     /**
+     * Returns the depth of this array, 0 if it's not an array
      * 
-     * @return the number of dimensions, at least 0
+     * @return The depth of this array, at least <code>0</code>
      * @since 2.0
      */
     int getDimensions();
@@ -372,6 +302,7 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
     /**
      * Gets bean properties without looking in superclasses or interfaces.
      *
+     * @return the bean properties
      * @since 1.3
      */
     List<BeanProperty> getBeanProperties();
@@ -379,6 +310,7 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
     /**
      * 
      * @param superclasses to define if superclasses should be included as well
+     * @return the bean properties
      * @since 1.3
      */
     List<BeanProperty> getBeanProperties( boolean superclasses );
@@ -387,6 +319,7 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
      * Gets bean property without looking in superclasses or interfaces.
      *
      * @param propertyName the name of the property
+     * @return the bean property
      * @since 1.3
      */
     BeanProperty getBeanProperty( String propertyName );
@@ -394,7 +327,7 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
     /**
      * @param propertyName the name of the property
      * @param superclasses to define if superclasses should be included as well
-     * 
+     * @return the bean property
      * @since 1.3
      */
     BeanProperty getBeanProperty( String propertyName, boolean superclasses );
@@ -402,6 +335,7 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
     /**
      * Equivalent of {@link Class#getClasses()}
      * Gets the known derived classes. That is, subclasses or implementing classes.
+     * @return the derived classes
      */
     List<JavaClass> getDerivedClasses();
 
@@ -419,11 +353,19 @@ public interface JavaClass extends JavaModel, JavaType, JavaClassParent, JavaAnn
     /**
      * Equivalent of {@link java.lang.Class#getName()}.
      * 
-     * @return the fully qualified name of the class
+     * @return the name of the entity (class, interface, array class, primitive type, or void) represented by this Class object, as a String.
      */
     String getName();
     
     /**
+     * Equivalent of {@link java.lang.Class#getSimpleName()}.
+     * 
+     * @return the simple name of the underlying class as given in the source code.
+     * @since 2.0
+     */
+    String getSimpleName();
+    
+    /**
      * Equivalent of {@link Class#getModifiers()}
      * 
      * <strong>This does not follow the java-api</strong>
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaConstructor.java b/src/main/java/com/thoughtworks/qdox/model/JavaConstructor.java
index b8406d3..dc11c43 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaConstructor.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaConstructor.java
@@ -30,69 +30,14 @@ import java.util.List;
  * @since 2.0
  */
 public interface JavaConstructor
-    extends JavaModel, JavaAnnotatedElement, JavaGenericDeclaration, JavaMember, ParameterDeclarator, Serializable
+    extends JavaModel, JavaAnnotatedElement, JavaGenericDeclaration, JavaMember, JavaExecutable, Serializable
 {
-    // Methods from Constructor
-      
-    /**
-     * Equivalent of {@link java.lang.reflect.Constructor#getParameterTypes()}, where a JavaParameter also contains the original name if available.
-     * 
-     * @return a list of JavaParameters, never <code>null</code>
-     */
-    List<JavaParameter> getParameters();
-
-    /**
-     * 
-     * @param name the name of the parameter
-     * @return the {@link JavaParameter} matching the name, otherwise <code>null</code>
-     */
-    JavaParameter getParameterByName( String name );
-    
-    /**
-     * Equivalent of {@link java.lang.reflect.Constructor#getParameterTypes()}
-     * 
-     * @return a list of JavaParameters, never <code>null</code>
-     */
-    List<JavaType> getParameterTypes();
-    
-    /**
-     * Equivalent of {@link java.lang.reflect.Constructor#getExceptionTypes()}
-     * 
-     * @return a list of Exceptions, never <code>null</code>
-     */
-    List<JavaClass> getExceptions();
-    
-    List<JavaType> getExceptionTypes();
- 
-    /**
-     * Equivalent of {@link java.lang.reflect.Constructor#isVarArgs()} 
-     * 
-     * @return <code>true</code> if the final parameter is a varArg, otherwise <code>false</code>
-     */
-    boolean isVarArgs();
-
-    // Extra source methods
-    
-    /**
-     * Retrieve the code between the brackets
-     * 
-     * @return the source code
-     */
-    String getSourceCode();
-    
-    /**
-     * Retrieve the complete codeblock of the constructor, including the sourcecode.
-     * 
-     * @return the code block
-     */
-    String getCodeBlock();
-
     // Utility methods
     
     /**
      * Returns <code>true</code> if this constructor matches the parameterTypes, assuming it's a non-varArg constructor.
      * 
-     * @param parameterTypes
+     * @param parameterTypes the parameter types
      * @return <code>true</code> if signature matches, otherwise <code>false</code>
      */
     boolean signatureMatches( List<JavaType> parameterTypes );
@@ -100,8 +45,8 @@ public interface JavaConstructor
     /**
      * Returns <code>true</code> if this constructor matches the parameterTypes and matches the varArg argument.
      * 
-     * @param parameterTypes
-     * @param varArgs 
+     * @param parameterTypes the parameter types
+     * @param varArgs {@code true} if the last argument should be a varArg, otherwise {@code false} 
      * @return <code>true</code> if signature matches, otherwise <code>false</code>
      */
     boolean signatureMatches( List<JavaType> parameterTypes, boolean varArgs );
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaExecutable.java b/src/main/java/com/thoughtworks/qdox/model/JavaExecutable.java
new file mode 100644
index 0000000..02bd52b
--- /dev/null
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaExecutable.java
@@ -0,0 +1,70 @@
+package com.thoughtworks.qdox.model;
+
+import java.util.List;
+
+/**
+ * A shared interface for the common functionality of Method and Constructor.
+ * 
+ * @author Robert Scholte
+ * @since 2.0
+ * 
+ * @see java.lang.reflect.Executable
+ */
+public interface JavaExecutable extends JavaMember, JavaGenericDeclaration
+{
+    JavaClass getDeclaringClass();
+    
+    /**
+     * Equivalent of {@link java.lang.reflect.Executable#getExceptionTypes()}
+     * 
+     * @return a list of Exceptions, never <code>null</code>
+     */
+    List<JavaClass> getExceptions();
+    
+    List<JavaType> getExceptionTypes();
+    
+    /**
+     * 
+     * @param name the name of the parameter
+     * @return the {@link JavaParameter} matching the name, otherwise <code>null</code>
+     */
+    JavaParameter getParameterByName( String name );
+    
+    /**
+     * Equivalent of {@link java.lang.reflect.Executable#getParameterTypes()}, where a JavaParameter also contains the original name if available.
+     * 
+     * @return a list of JavaParameters, never <code>null</code>
+     */
+    List<JavaParameter> getParameters();
+    
+    /**
+     * Equivalent of {@link java.lang.reflect.Executable#getParameterTypes()}
+     * 
+     * @return a list of JavaParameters, never <code>null</code>
+     * @since 1.12 
+     */
+    List<JavaType> getParameterTypes();
+
+    /**
+     * If a class inherits this method from a generic class or interface, you can use this method to get the resolved parameter types
+     * 
+     * @param resolve {@code true} if the resolved types should be returned, otherwise {@code false}
+     * @return the parameter types
+     * @since 1.12
+     */
+    List<JavaType> getParameterTypes( boolean resolve );
+    
+    /**
+     * Get the original source code of the body of this method.
+     *
+     * @return Code as string.
+     */
+    String getSourceCode();
+    
+    /**
+     * Equivalent of {@link java.lang.reflect.Executable#isVarArgs()} 
+     * 
+     * @return <code>true</code> if the final parameter is a varArg, otherwise <code>false</code>
+     */
+    boolean isVarArgs();
+}
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaField.java b/src/main/java/com/thoughtworks/qdox/model/JavaField.java
index ff23a05..c8c6d0c 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaField.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaField.java
@@ -48,12 +48,6 @@ public interface JavaField extends JavaAnnotatedElement, JavaMember, JavaModel
      */
     String getCodeBlock();
 
-    @Deprecated
-    String getDeclarationSignature( boolean withModifiers );
-
-    @Deprecated
-    String getCallSignature();
-
     /**
      * Get the original expression used to initialize the field.
      *
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaGenericDeclaration.java b/src/main/java/com/thoughtworks/qdox/model/JavaGenericDeclaration.java
index 6a0c612..afbe7ef 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaGenericDeclaration.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaGenericDeclaration.java
@@ -33,6 +33,7 @@ public interface JavaGenericDeclaration
     /**
      * Equivalent of {@link java.lang.reflect.GenericDeclaration#getTypeParameters()}
      * 
+     * @param <D> the type
      * @return a list of typeParameters, never <code>null</code> 
      */
     <D extends JavaGenericDeclaration> List<JavaTypeVariable<D>> getTypeParameters();
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaMethod.java b/src/main/java/com/thoughtworks/qdox/model/JavaMethod.java
index d859198..5bbc4c9 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaMethod.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaMethod.java
@@ -21,54 +21,23 @@ package com.thoughtworks.qdox.model;
 
 import java.util.List;
 
-public interface JavaMethod extends JavaAnnotatedElement, JavaMember, JavaModel, JavaGenericDeclaration, ParameterDeclarator
+public interface JavaMethod extends JavaAnnotatedElement, JavaMember, JavaModel, JavaGenericDeclaration, JavaExecutable
 {
-    
-    // deprecated methods
-    // will be removed with QDox-2.0
-
-    /**
-     * Equivalent of java.lang.reflect.Method.getGenericReturnType()
-     * 
-     * @return the generic return type
-     * @since 1.12
-     * @deprecated use {@link #getReturnType()} instead, this one holds generic information
-     */
-    JavaClass getGenericReturnType();
-
-    /**
-     * @deprecated use {@link #getDeclaringClass()} instead
-     */
-    JavaClass getParentClass();
-
     /**
      * 
      * @return the return type
      */
     JavaClass getReturns();
 
-    List<JavaParameter> getParameters();
-
-    JavaParameter getParameterByName( String name );
-
-    List<JavaClass> getExceptions();
-
-    List<JavaType> getExceptionTypes();
-
-    /**
-     * Equivalent of {@link java.lang.reflect.Method#isVarArgs()}
-     * 
-     * @return <code>true</code> if this method was declared to take a variable number of arguments, 
-     *          otherwise <code>false</code>
-     */
-    boolean isVarArgs();
-
     /**
+     * @param withModifiers {@code true} if modifiers should be added, otherwise {@code false}
+     * @return the declaration signature
      * @since 1.3
      */
     String getDeclarationSignature( boolean withModifiers );
 
     /**
+     * @return the call signature
      * @since 1.3
      */
     String getCallSignature();
@@ -138,12 +107,6 @@ public interface JavaMethod extends JavaAnnotatedElement, JavaMember, JavaModel,
 
     List<DocletTag> getTagsByName( String name, boolean inherited );
 
-    /**
-     * Get the original source code of the body of this method.
-     *
-     * @return Code as string.
-     */
-    String getSourceCode();
     
     /**
      * Equivalent of java.lang.reflect.Method.getReturnType()
@@ -162,22 +125,6 @@ public interface JavaMethod extends JavaAnnotatedElement, JavaMember, JavaModel,
      */
     JavaType getReturnType( boolean resolve );
 
-    /**
-     * 
-     * @return the parameter types
-     * @since 1.12
-     */
-    List<JavaType> getParameterTypes();
-
-    /**
-     * If a class inherits this method from a generic class or interface, you can use this method to get the resolved parameter types
-     * 
-     * @param resolve
-     * @return the parameter types
-     * @since 1.12
-     */
-    List<JavaType> getParameterTypes( boolean resolve );
-
     DocletTag getTagByName( String string, boolean b );
     
     /**
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaModel.java b/src/main/java/com/thoughtworks/qdox/model/JavaModel.java
index 4b0ffd1..fc40532 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaModel.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaModel.java
@@ -30,13 +30,6 @@ public interface JavaModel extends Serializable
     String getCodeBlock();
 
     /**
-     * The compilation unit, which includes the imports, the public and anonymous classes
-     * 
-     * @return the {@link JavaSource} of this element
-     */
-    JavaSource getSource();
-    
-    /**
      * The line number where this element started
      * 
      * @return the line number of this element
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaModelUtils.java b/src/main/java/com/thoughtworks/qdox/model/JavaModelUtils.java
index 3772564..fc6bbe3 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaModelUtils.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaModelUtils.java
@@ -34,15 +34,15 @@ public final class JavaModelUtils
      * </p>
      * <strong>Note:</strong>the name must match the {@code cls} itself or one of its nested classes.
      * 
-     * @param cls 
-     * @param name 
+     * @param cls the declaring class
+     * @param name the name
      * @return the matching class, otherwise <code>null</code>
      * @see JavaClass#getJavaClassLibrary()
      */
     public static JavaClass getClassByName( JavaClass cls, String name )
     {
         JavaClass result = null;
-        if ( cls.getFullyQualifiedName().equals( name ) )
+        if ( cls.getBinaryName().equals( name ) )
         {
             result = cls;
         }
@@ -52,7 +52,7 @@ public final class JavaModelUtils
         }
         else
         {
-            for ( JavaClass innerCls : cls.getClasses() )
+            for ( JavaClass innerCls : cls.getNestedClasses() )
             {
                 result = getClassByName( innerCls, name );
                 if ( result != null )
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaModule.java b/src/main/java/com/thoughtworks/qdox/model/JavaModule.java
new file mode 100644
index 0000000..63fe25c
--- /dev/null
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaModule.java
@@ -0,0 +1,12 @@
+package com.thoughtworks.qdox.model;
+
+public interface JavaModule
+{
+    String getName();
+    
+    boolean isNamed();
+    
+    JavaModuleDescriptor getDescriptor();
+    
+    
+}
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaModuleDescriptor.java b/src/main/java/com/thoughtworks/qdox/model/JavaModuleDescriptor.java
new file mode 100644
index 0000000..8e61c81
--- /dev/null
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaModuleDescriptor.java
@@ -0,0 +1,104 @@
+package com.thoughtworks.qdox.model;
+
+import java.util.Collection;
+
+public interface JavaModuleDescriptor
+{
+    boolean isOpen();
+    
+    String getName();
+    
+    Collection<JavaExports> getExports();
+
+    Collection<JavaOpens> getOpens();
+
+    Collection<JavaProvides> getProvides();
+
+    Collection<JavaRequires> getRequires();
+
+    Collection<JavaUses> getUses();
+
+    /**
+     * Represents the following ModuleStatement:<br>
+     * <code>
+     * exports SOURCE [to TARGET{, TARGET}];
+     * </code>
+     * where SOURCE matches a PackageName and TARGET matches a ModuleName
+     *  
+     * @author Robert Scholte
+     */
+    static interface JavaExports {
+        JavaPackage getSource();
+        
+        Collection<JavaModule> getTargets();
+    }
+
+    /**
+     * Represents the following ModuleStatement:<br>
+     * <code>
+     * opens SOURCE [to TARGET{, TARGET}];
+     * </code>
+     * where SOURCE matches a PackageName and TARGET matches a ModuleName
+     *  
+     * @author Robert Scholte
+     */
+    static interface JavaOpens {
+        JavaPackage getSource();
+        
+        Collection<JavaModule> getTargets();
+    }
+
+    /**
+     * Represents the following ModuleStatement:<br>
+     * <code>
+     * provides SERVICE with PROVIDER;
+     * </code>
+     * where SERVICE matches a TypeName and TARGET matches a TypeName
+     * 
+     * @author Robert Scholte
+     *
+     */
+    static interface JavaProvides {
+        JavaClass getService();
+        
+        Collection<JavaClass> getProviders();
+    }
+    
+    /**
+     * Represents the following ModuleStatement:<br>
+     * <code>
+     * requires [public] [static] NAME;
+     * </code>
+     * Where NAME matches a ModuleName
+     * 
+     * @author Robert Scholte
+     *
+     */
+    static interface JavaRequires {
+    
+        JavaModule getModule();
+        
+        boolean isTransitive();
+        
+        boolean isStatic();
+
+        Collection<String> getModifiers();
+    }
+    
+    /**
+     * Represents the following ModuleStatement:<br>
+     * <code>
+     * uses NAME;
+     * </code>
+     * Where NAME matches a TypeName
+     * 
+     * @author Robert Scholte
+     *
+     */
+    static interface JavaUses 
+    {
+        JavaClass getService();
+    }
+    
+    
+}
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaParameter.java b/src/main/java/com/thoughtworks/qdox/model/JavaParameter.java
index f80c912..034c2dc 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaParameter.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaParameter.java
@@ -47,18 +47,19 @@ public interface JavaParameter extends JavaAnnotatedElement, JavaType
      * 
      * @return the declaring method or constructor
      */
-    ParameterDeclarator getDeclarator();
+    JavaExecutable getExecutable();
 
     /**
      * The declaring class of the declaring method of this parameter.
      * 
      * @return the declaring class of the declaring method
      */
-    JavaClass getParentClass();
+    JavaClass getDeclaringClass();
 
     /**
      * Is this a Java 5 var args type specified using three dots. e.g. <code>void doStuff(Object... thing)</code>
      * 
+     * @return {@code true} if this parameter is a varArg, otherwise {@code false}
      * @since 1.6
      */
     boolean isVarArgs();
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaSource.java b/src/main/java/com/thoughtworks/qdox/model/JavaSource.java
index 141e25f..606b856 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaSource.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaSource.java
@@ -23,17 +23,17 @@ import java.net.URL;
 import java.util.List;
 
 import com.thoughtworks.qdox.library.ClassLibrary;
-import com.thoughtworks.qdox.model.impl.JavaClassParent;
 
 /**
  * The root of every JavaModel, even for those based on binary classes.
  * 
  * @author Robert Scholte
  */
-public interface JavaSource extends JavaClassParent
+public interface JavaSource
 {
 
     /**
+     * @return the URL of the source file
      * @since 1.4
      */
     URL getURL();
@@ -67,23 +67,6 @@ public interface JavaSource extends JavaClassParent
     String getCodeBlock();
 
     /**
-     * @deprecated use {@link #resolveCanonicalName(String)} or {@link #resolveFullyQualifiedName(String)} instead
-     */
-    String resolveType( String typeName );
-
-    /**
-     * @param name the simple name or canonical name of a class
-     * @return the resolved canonical name, otherwise <code>null</code>
-     */
-    String resolveCanonicalName( String name );
-    
-    /**
-     * @param name the simple name or canonical name of a class
-     * @return the resolved fully qualified name, otherwise <code>null</code>
-     */
-    String resolveFullyQualifiedName( String name );
-
-    /**
      * If there's a package, return the packageName, followed by a dot, otherwise an empty String
      * 
      * @return the class name prefix, otherwise an empty String
@@ -94,6 +77,7 @@ public interface JavaSource extends JavaClassParent
      * Try to get the JavaClass child based on its name relative to the package.
      * This doesn't try to resolve it by recursion.
      * 
+     * @param name the name of the class
      * @return the resolved JavaClass, otherwise <code>null</code>
      */
     JavaClass getNestedClassByName( String name );
diff --git a/src/main/java/com/thoughtworks/qdox/model/JavaType.java b/src/main/java/com/thoughtworks/qdox/model/JavaType.java
index d85b4e2..0763de7 100644
--- a/src/main/java/com/thoughtworks/qdox/model/JavaType.java
+++ b/src/main/java/com/thoughtworks/qdox/model/JavaType.java
@@ -25,46 +25,21 @@ package com.thoughtworks.qdox.model;
  */
 public interface JavaType
 {
-    JavaType VOID = new JavaType() 
-    {
-        private final String value = "void";
-
-        public String getCanonicalName()
-        {
-            return value;
-        }
-
-        public String getGenericCanonicalName()
-        {
-            return value;
-        }
-
-        public String getFullyQualifiedName()
-        {
-            return value;
-        }
-
-        public String getGenericFullyQualifiedName()
-        {
-            return value;
-        }
-
-        public String getValue()
-        {
-            return value;
-        }
-
-        public String getGenericValue()
-        {
-            return value;
-        }
-
-        public String toGenericString()
-        {
-            return value;
-        }
-    };
-
+    /**
+     * <blockquote>
+     * The class or interface must be named by its binary name, which must meet the following constraints:
+     * <ul>
+     *   <li>The binary name of a top level type is its canonical name.</li>
+     *   <li>The binary name of a member type consists of the binary name of its immediately enclosing type, followed by $, followed by the simple name of the member.</li>
+     * </ul>
+     * </blockquote>
+     * 
+     * @return the binary name
+     * @since 2.0
+     * @see <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1">https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1</a>
+     */
+    String getBinaryName();
+    
     /**
      * Equivalent of (@link {@link java.lang.Class#getCanonicalName()}.
      * 
@@ -80,28 +55,44 @@ public interface JavaType
     String getGenericCanonicalName();
 
     /**
-     * Returns the FQN of an Object or the handler of a Type.
-     * If the name of the can't be resolved based on the imports and the classes on the classpath the name will be returned.
-     * InnerClasses will use the $ sign.
-     * If the type is an array, the brackets will be included. The get only the name, use {@link #getComponentType()}.
+     * <blockquote>
+     * Every primitive type, named package, top level class, and top level interface has a fully qualified name:
+     * <ul>
+     *   <li>The fully qualified name of a primitive type is the keyword for that primitive type, namely byte, short, char, int, long, float, double, or boolean.</li>
+     *   <li>The fully qualified name of a named package that is not a subpackage of a named package is its simple name.</li>
+     *   <li>The fully qualified name of a named package that is a subpackage of another named package consists of the fully qualified name of the containing package, followed by ".", followed by the simple (member) name of the subpackage.</li>
+     *   <li>The fully qualified name of a top level class or top level interface that is declared in an unnamed package is the simple name of the class or interface.</li>
+     *   <li>The fully qualified name of a top level class or top level interface that is declared in a named package consists of the fully qualified name of the package, followed by ".", followed by the simple name of the class or interface.</li>
+     * </ul>
+     * Each member class, member interface, and array type may have a fully qualified name:
+     * <ul>
+     *   <li>A member class or member interface M of another class or interface C has a fully qualified name if and only if C has a fully qualified name.</li>
+     *   <li>In that case, the fully qualified name of M consists of the fully qualified name of C, followed by ".", followed by the simple name of M.</li>
+     *   <li>An array type has a fully qualified name if and only if its element type has a fully qualified name.</li>
+     *   <li>In that case, the fully qualified name of an array type consists of the fully qualified name of the component type of the array type followed by "[]".</li>
+     * </ul>
+     * </blockquote>
      * 
      * Some examples how names will be translated 
      * <pre>
-     * Object > java.lang.Object
-     * java.util.List > java.util.List
-     * ?  > ?
-     * T  > T
-     * anypackage.Outer.Inner > anypackage.Outer$Inner
-     * String[][] > java.lang.String[][]
+     * Object > java.lang.Object
+     * java.util.List > java.util.List
+     * ?  > ?
+     * T  > T
+     * anypackage.Outer.Inner > anypackage.Outer.Inner
+     * String[][] > java.lang.String[][]
      * </pre>
      * 
      * @return the fully qualified name, never <code>null</code>
-     * @see #getComponentType()
+     * @see JavaClass#getComponentType()
+     * @see #getBinaryName()
+     * @see <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.7">https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.7</a>
      */
+    // @TODO make clear difference between FQN and canonicalName, specs say FQN can be null
     String getFullyQualifiedName();
 
     /**
-     * The fully qualified nate with generic information.
+     * The fully qualified name with generic information.
      * 
      * @return the generic fully qualified name
      */
@@ -114,9 +105,9 @@ public interface JavaType
      * 
      * Examples:
      * <pre>
-     *  private String fieldA;           // getValue() will return "String"
-     *  private java.lang.String fieldA; // getValue() will return "java.lang.String"
-     *  private List<String> aList;      // getValue() will return "List"
+     *  private String fieldA;             // getValue() will return "String"
+     *  private java.lang.String fieldA;   // getValue() will return "java.lang.String"
+     *  private List>String> aList;  // getValue() will return "List"
      * </pre>
      * 
      * @return the name of the class as used in the source
@@ -129,14 +120,13 @@ public interface JavaType
      * 
      * Examples:
      * <pre>
-     *  private String fieldA;           // getValue() will return "String"
-     *  private java.lang.String fieldA; // getValue() will return "java.lang.String"
-     *  private List<String> aList;      // getValue() will return "List<String>"
+     *  private String fieldA;             // getValue() will return "String"
+     *  private java.lang.String fieldA;   // getValue() will return "java.lang.String"
+     *  private List>String> aList;  // getValue() will return "List>String>"
      * </pre>
      * @return the generic name of the class as used in the source
      */
     String getGenericValue();
 
-    @Deprecated
     String toGenericString();
 }
\ No newline at end of file
diff --git a/src/main/java/com/thoughtworks/qdox/model/ParameterDeclarator.java b/src/main/java/com/thoughtworks/qdox/model/ParameterDeclarator.java
deleted file mode 100644
index 01b4d66..0000000
--- a/src/main/java/com/thoughtworks/qdox/model/ParameterDeclarator.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.thoughtworks.qdox.model;
-
-/**
- * Can either be a Method or a Constructor
- * 
- * @author Robert Scholte
- * @since 2.0
- */
-public interface ParameterDeclarator extends JavaGenericDeclaration 
-{
-    JavaClass getParentClass();
-
-}
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Add.java b/src/main/java/com/thoughtworks/qdox/model/expression/Add.java
index 89905fb..74db78d 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Add.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Add.java
@@ -28,16 +28,19 @@ public class Add
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " + " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " + " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/And.java b/src/main/java/com/thoughtworks/qdox/model/expression/And.java
index 281cd11..f319253 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/And.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/And.java
@@ -28,16 +28,19 @@ public class And
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " & " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " & " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/AnnotationValueList.java b/src/main/java/com/thoughtworks/qdox/model/expression/AnnotationValueList.java
index 94ab843..4a0234d 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/AnnotationValueList.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/AnnotationValueList.java
@@ -39,6 +39,7 @@ public class AnnotationValueList
         return valueList;
     }
 
+    @Override
     public String toString()
     {
         StringBuilder buf = new StringBuilder();
@@ -60,20 +61,13 @@ public class AnnotationValueList
         return buf.toString();
     }
 
-    /*
-     * (non-Javadoc)
-     * @see com.thoughtworks.qdox.model.expression.AnnotationValue#accept(com.thoughtworks.qdox.model.expression.
-     * AnnotationVisitor)
-     */
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
-    /*
-     * (non-Javadoc)
-     * @see com.thoughtworks.qdox.model.expression.AnnotationValue#getParameterValue()
-     */
+    /** {@inheritDoc} */
     public List<Object> getParameterValue()
     {
         List<Object> list = new LinkedList<Object>();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Cast.java b/src/main/java/com/thoughtworks/qdox/model/expression/Cast.java
index ae70c27..2c88a88 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Cast.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Cast.java
@@ -45,16 +45,19 @@ public class Cast
         return this.value;
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return "(" + type.getCanonicalName() + ") " + value.getParameterValue();
     }
 
+    @Override
     public String toString()
     {
         return "(" + type.toString() + ") " + value.toString();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Constant.java b/src/main/java/com/thoughtworks/qdox/model/expression/Constant.java
index c31ee80..e44e33f 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Constant.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Constant.java
@@ -100,16 +100,19 @@ public abstract class Constant
         return image;
     }
 
+    @Override
     public String toString()
     {
         return image;
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return image;
@@ -294,8 +297,12 @@ public abstract class Constant
 
     /**
      * Convert a character literal into a character.
+     * 
+     * @param value the single quoted value
+     * @return the transformed char
+     * @throws IllegalArgumentException if value is not a character literal
      */
-    protected static Character toChar( String value )
+    protected static Character toChar( String value ) throws IllegalArgumentException
     {
         if ( !value.startsWith( "'" ) && !value.endsWith( "'" ) )
         {
@@ -314,8 +321,12 @@ public abstract class Constant
 
     /**
      * Convert a string literal into a string.
+     * 
+     * @param value the double quoted value
+     * @return the transformed String
+     * @throws IllegalArgumentException if value is not a String literal
      */
-    protected static String toString( String value )
+    protected static String toString( String value ) throws IllegalArgumentException
     {
         if ( value.length() < 2 && !value.startsWith( "\"" ) && !value.endsWith( "\"" ) )
         {
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Divide.java b/src/main/java/com/thoughtworks/qdox/model/expression/Divide.java
index f2465e5..359d454 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Divide.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Divide.java
@@ -28,16 +28,19 @@ public class Divide
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " / " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " / " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Equals.java b/src/main/java/com/thoughtworks/qdox/model/expression/Equals.java
index 42c02bc..74816ae 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Equals.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Equals.java
@@ -28,16 +28,19 @@ public class Equals
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " == " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " == " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/ExclusiveOr.java b/src/main/java/com/thoughtworks/qdox/model/expression/ExclusiveOr.java
index 7009435..bf2f556 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/ExclusiveOr.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/ExclusiveOr.java
@@ -28,16 +28,19 @@ public class ExclusiveOr
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " ^ " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " ^ " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Expression.java b/src/main/java/com/thoughtworks/qdox/model/expression/Expression.java
index c7d3935..b37a70f 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Expression.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Expression.java
@@ -22,7 +22,7 @@ package com.thoughtworks.qdox.model.expression;
 public interface Expression
 {
     /**
-     * Get a parameter value for {@link JavaAnnotation#getNamedParameter(String)}.
+     * Get a parameter value for {@link com.thoughtworks.qdox.model.JavaAnnotation#getNamedParameter(String)}.
      * 
      * @return Parameter value
      */
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/FieldRef.java b/src/main/java/com/thoughtworks/qdox/model/expression/FieldRef.java
index d53e320..38021a9 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/FieldRef.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/FieldRef.java
@@ -22,12 +22,8 @@ package com.thoughtworks.qdox.model.expression;
 import java.util.StringTokenizer;
 
 import com.thoughtworks.qdox.library.ClassLibrary;
-import com.thoughtworks.qdox.model.JavaAnnotatedElement;
 import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaField;
-import com.thoughtworks.qdox.model.JavaMember;
-import com.thoughtworks.qdox.model.JavaPackage;
-import com.thoughtworks.qdox.model.JavaParameter;
 
 public class FieldRef
     implements AnnotationValue
@@ -36,7 +32,9 @@ public class FieldRef
 
     private final String name;
 
-    private JavaAnnotatedElement context;
+    private JavaClass declaringClass;
+    
+    private ClassLibrary classLibrary;
 
     private JavaField field;
 
@@ -81,6 +79,7 @@ public class FieldRef
         return parts.length - 1;
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
@@ -92,14 +91,20 @@ public class FieldRef
         return getName();
     }
 
+    @Override
     public String toString()
     {
         return getName();
     }
 
-    public void setContext( JavaAnnotatedElement context )
+    public void setDeclaringClass( JavaClass declaringClass )
+    {
+        this.declaringClass = declaringClass;
+    }
+    
+    public void setClassLibrary( ClassLibrary classLibrary )
     {
-        this.context = context;
+        this.classLibrary = classLibrary;
     }
 
     public String getClassPart()
@@ -179,44 +184,11 @@ public class FieldRef
 
     private JavaClass getDeclaringClass()
     {
-        JavaClass result = null;
-        if ( context instanceof JavaMember )
-        {
-            result = ( (JavaMember) context ).getDeclaringClass();
-        }
-        else if ( context instanceof JavaClass )
-        {
-            result = ( (JavaClass) context ).getDeclaringClass();
-        }
-        else if ( context instanceof JavaParameter )
-        {
-            result = ( (JavaParameter) context ).getParentClass();
-        }
-        // else if ( context instanceof JavaPackage )
-        // {
-        // }
-        return result;
+        return declaringClass;
     }
 
     private ClassLibrary getClassLibrary()
     {
-        ClassLibrary result = null;
-        if ( context instanceof JavaPackage )
-        {
-            result = ( (JavaPackage) context ).getJavaClassLibrary();
-        }
-        else if ( context instanceof JavaClass )
-        {
-            result = ( (JavaClass) context ).getJavaClassLibrary();
-        }
-        else
-        {
-            JavaClass declaringClass = getDeclaringClass();
-            if ( declaringClass != null )
-            {
-                result = declaringClass.getJavaClassLibrary();
-            }
-        }
-        return result;
+        return classLibrary;
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/GreaterEquals.java b/src/main/java/com/thoughtworks/qdox/model/expression/GreaterEquals.java
index 9ca982b..2e5bd84 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/GreaterEquals.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/GreaterEquals.java
@@ -28,16 +28,19 @@ public class GreaterEquals
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " >= " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " >= " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/GreaterThan.java b/src/main/java/com/thoughtworks/qdox/model/expression/GreaterThan.java
index ae8f57b..b6b30ec 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/GreaterThan.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/GreaterThan.java
@@ -28,16 +28,19 @@ public class GreaterThan
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " > " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " > " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/LessEquals.java b/src/main/java/com/thoughtworks/qdox/model/expression/LessEquals.java
index 3255d60..fb34326 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/LessEquals.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/LessEquals.java
@@ -28,16 +28,19 @@ public class LessEquals
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " <= " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " <= " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/LessThan.java b/src/main/java/com/thoughtworks/qdox/model/expression/LessThan.java
index 62d7a3a..6c6cde8 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/LessThan.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/LessThan.java
@@ -28,16 +28,19 @@ public class LessThan
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " < " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " < " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/LogicalAnd.java b/src/main/java/com/thoughtworks/qdox/model/expression/LogicalAnd.java
index 5e4acb7..927cb84 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/LogicalAnd.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/LogicalAnd.java
@@ -28,16 +28,19 @@ public class LogicalAnd
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " && " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " && " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/LogicalNot.java b/src/main/java/com/thoughtworks/qdox/model/expression/LogicalNot.java
index 7233e16..6ed6705 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/LogicalNot.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/LogicalNot.java
@@ -28,16 +28,19 @@ public class LogicalNot
         super( value );
     }
 
+    @Override
     public String toString()
     {
         return "!" + getValue().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return "!" + getValue().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/LogicalOr.java b/src/main/java/com/thoughtworks/qdox/model/expression/LogicalOr.java
index b5585cd..def431c 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/LogicalOr.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/LogicalOr.java
@@ -28,16 +28,19 @@ public class LogicalOr
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " || " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " || " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/MethodInvocation.java b/src/main/java/com/thoughtworks/qdox/model/expression/MethodInvocation.java
index 2f9e747..e381520 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/MethodInvocation.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/MethodInvocation.java
@@ -34,6 +34,7 @@ public class MethodInvocation
         this.arguments = arguments;
     }
 
+    /** {@inheritDoc} */
     public Object getParameterValue()
     {
         return null;
@@ -49,6 +50,7 @@ public class MethodInvocation
         return arguments;
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/MinusSign.java b/src/main/java/com/thoughtworks/qdox/model/expression/MinusSign.java
index 2350994..6fe2e91 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/MinusSign.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/MinusSign.java
@@ -28,16 +28,19 @@ public class MinusSign
         super( value );
     }
 
+    @Override
     public String toString()
     {
         return "-" + getValue().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return "-" + getValue().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Multiply.java b/src/main/java/com/thoughtworks/qdox/model/expression/Multiply.java
index 2eb4073..971ca51 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Multiply.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Multiply.java
@@ -28,16 +28,19 @@ public class Multiply
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " * " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " * " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Not.java b/src/main/java/com/thoughtworks/qdox/model/expression/Not.java
index 9c2ba74..9321ebf 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Not.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Not.java
@@ -28,16 +28,19 @@ public class Not
         super( value );
     }
 
+    @Override
     public String toString()
     {
         return "~" + getValue().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return "~" + getValue().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/NotEquals.java b/src/main/java/com/thoughtworks/qdox/model/expression/NotEquals.java
index 7c3df44..ae836c9 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/NotEquals.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/NotEquals.java
@@ -28,16 +28,19 @@ public class NotEquals
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " != " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " != " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Or.java b/src/main/java/com/thoughtworks/qdox/model/expression/Or.java
index 1c7cffc..fb7ea47 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Or.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Or.java
@@ -28,16 +28,19 @@ public class Or
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " | " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " | " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/ParenExpression.java b/src/main/java/com/thoughtworks/qdox/model/expression/ParenExpression.java
index 62fc77b..90cdb1b 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/ParenExpression.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/ParenExpression.java
@@ -35,16 +35,19 @@ public class ParenExpression
         return value;
     }
 
+    @Override
     public String toString()
     {
         return "(" + value.toString() + ")";
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return "(" + value.getParameterValue() + ")";
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/PlusSign.java b/src/main/java/com/thoughtworks/qdox/model/expression/PlusSign.java
index 5d4134d..79e4915 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/PlusSign.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/PlusSign.java
@@ -28,16 +28,19 @@ public class PlusSign
         super( value );
     }
 
+    @Override
     public String toString()
     {
         return "+" + getValue().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return "+" + getValue().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Query.java b/src/main/java/com/thoughtworks/qdox/model/expression/Query.java
index 48d9c05..a336f85 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Query.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Query.java
@@ -36,6 +36,7 @@ public class Query
         this.falseExpression = falseExpression;
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
@@ -56,12 +57,14 @@ public class Query
         return this.falseExpression;
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return condition.getParameterValue().toString() + " ? " + trueExpression.getParameterValue() + " : "
             + falseExpression.getParameterValue();
     }
 
+    @Override
     public String toString()
     {
         return condition.toString() + " ? " + trueExpression.toString() + " : " + falseExpression.toString();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Remainder.java b/src/main/java/com/thoughtworks/qdox/model/expression/Remainder.java
index fd76b50..074692d 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Remainder.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Remainder.java
@@ -28,16 +28,19 @@ public class Remainder
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " * " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " * " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/ShiftLeft.java b/src/main/java/com/thoughtworks/qdox/model/expression/ShiftLeft.java
index a6f1007..25b619b 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/ShiftLeft.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/ShiftLeft.java
@@ -28,16 +28,19 @@ public class ShiftLeft
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " << " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " << " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/ShiftRight.java b/src/main/java/com/thoughtworks/qdox/model/expression/ShiftRight.java
index f2dbb1c..133c7b4 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/ShiftRight.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/ShiftRight.java
@@ -28,16 +28,19 @@ public class ShiftRight
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " >> " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " >> " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/Subtract.java b/src/main/java/com/thoughtworks/qdox/model/expression/Subtract.java
index 47f3185..75f4e7b 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/Subtract.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/Subtract.java
@@ -28,16 +28,19 @@ public class Subtract
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " - " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " - " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/TypeRef.java b/src/main/java/com/thoughtworks/qdox/model/expression/TypeRef.java
index 382e45f..1957b86 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/TypeRef.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/TypeRef.java
@@ -37,16 +37,19 @@ public class TypeRef
         return type;
     }
 
+    @Override
     public String toString()
     {
         return type.getValue() + ".class";
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return type.getValue() + ".class";
diff --git a/src/main/java/com/thoughtworks/qdox/model/expression/UnsignedShiftRight.java b/src/main/java/com/thoughtworks/qdox/model/expression/UnsignedShiftRight.java
index 69215cf..4e2baa7 100644
--- a/src/main/java/com/thoughtworks/qdox/model/expression/UnsignedShiftRight.java
+++ b/src/main/java/com/thoughtworks/qdox/model/expression/UnsignedShiftRight.java
@@ -28,16 +28,19 @@ public class UnsignedShiftRight
         super( left, right );
     }
 
+    @Override
     public String toString()
     {
         return getLeft().toString() + " >>> " + getRight().toString();
     }
 
+    /** {@inheritDoc} */
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
     }
 
+    /** {@inheritDoc} */
     public String getParameterValue()
     {
         return getLeft().getParameterValue() + " >>> " + getRight().getParameterValue();
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/AbstractBaseJavaEntity.java b/src/main/java/com/thoughtworks/qdox/model/impl/AbstractBaseJavaEntity.java
index 7548752..0a50de5 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/AbstractBaseJavaEntity.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/AbstractBaseJavaEntity.java
@@ -27,9 +27,12 @@ import java.util.List;
 import com.thoughtworks.qdox.model.DocletTag;
 import com.thoughtworks.qdox.model.JavaAnnotation;
 import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaSource;
 
 public abstract class AbstractBaseJavaEntity extends AbstractJavaModel implements Serializable {
 
+    private JavaSource source;
+    
 	private List<JavaAnnotation> annotations = Collections.emptyList();
 	private String comment;
 	private List<DocletTag> tags = Collections.emptyList();
@@ -39,6 +42,14 @@ public abstract class AbstractBaseJavaEntity extends AbstractJavaModel implement
         super();
     }
 
+    public JavaSource getSource() {
+        return source;
+    }
+    
+    public void setSource(JavaSource source) {
+        this.source = source;
+    }
+    
     public List<JavaAnnotation> getAnnotations()
     {
         return annotations;
@@ -55,7 +66,7 @@ public abstract class AbstractBaseJavaEntity extends AbstractJavaModel implement
 	 * 
 	 * @return the surrounding class
 	 */
-    public JavaClass getParentClass()
+    public JavaClass getDeclaringClass()
     {
         return null;
     }
@@ -105,6 +116,7 @@ public abstract class AbstractBaseJavaEntity extends AbstractJavaModel implement
      * 
      * @param tagName the name of the docletTag
      * @param parameterName the name of the parameter
+     * @return the value of the named parameter 
      * @since 1.3
      */
     public String getNamedParameter( String tagName, String parameterName )
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/AbstractJavaEntity.java b/src/main/java/com/thoughtworks/qdox/model/impl/AbstractJavaEntity.java
index da215b4..6e7175f 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/AbstractJavaEntity.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/AbstractJavaEntity.java
@@ -28,7 +28,7 @@ import com.thoughtworks.qdox.model.JavaModel;
 public abstract class AbstractJavaEntity extends AbstractBaseJavaEntity implements JavaModel {
 
     private List<String> modifiers = Collections.emptyList();
-    private JavaClass parentCls;
+    private JavaClass declaringClass;
 	private String name;
 
 	/**
@@ -156,14 +156,15 @@ public abstract class AbstractJavaEntity extends AbstractBaseJavaEntity implemen
         return modifiers.contains(modifier);
     }
 
-    public void setParentClass( JavaClass parentClass )
+    public void setDeclaringClass( JavaClass declaringClass )
     {
-        this.parentCls = parentClass;
+        this.declaringClass = declaringClass;
     }
-    
-    public JavaClass getParentClass()
+
+    /** {@inheritDoc} */
+    public JavaClass getDeclaringClass()
     {
-        return parentCls;
+        return declaringClass;
     }
 
 	public String getName() {
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/AbstractJavaModel.java b/src/main/java/com/thoughtworks/qdox/model/impl/AbstractJavaModel.java
index 3861b02..9145752 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/AbstractJavaModel.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/AbstractJavaModel.java
@@ -1,7 +1,6 @@
 package com.thoughtworks.qdox.model.impl;
 
 import com.thoughtworks.qdox.model.JavaModel;
-import com.thoughtworks.qdox.model.JavaSource;
 import com.thoughtworks.qdox.writer.ModelWriter;
 import com.thoughtworks.qdox.writer.ModelWriterFactory;
 import com.thoughtworks.qdox.writer.impl.DefaultModelWriter;
@@ -17,7 +16,6 @@ import com.thoughtworks.qdox.writer.impl.DefaultModelWriter;
 public abstract class AbstractJavaModel implements JavaModel {
 
     private ModelWriterFactory modelWriterFactory;
-    private JavaSource source;
     
 	private int lineNumber = -1;
 
@@ -25,6 +23,7 @@ public abstract class AbstractJavaModel implements JavaModel {
 		super();
 	}
 
+	/** {@inheritDoc} */
 	public int getLineNumber() {
 		return lineNumber;
 	}
@@ -33,17 +32,9 @@ public abstract class AbstractJavaModel implements JavaModel {
 	    this.lineNumber = lineNumber;
 	}
 
-	public JavaSource getSource() {
-		return source;
-	}
-	
-	public void setSource(JavaSource source) {
-		this.source = source;
-	}
-	
 	/**
      * 
-     * @param modelWriterFactory
+     * @param modelWriterFactory the modelWriterFactory
      * @since 2.0
      */
     public void setModelWriterFactory( ModelWriterFactory modelWriterFactory )
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultDocletTagFactory.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultDocletTagFactory.java
index 8416fa4..58e914e 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultDocletTagFactory.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultDocletTagFactory.java
@@ -29,6 +29,7 @@ import com.thoughtworks.qdox.model.JavaAnnotatedElement;
  */
 public class DefaultDocletTagFactory implements DocletTagFactory {
 
+    /** {@inheritDoc} */
     public DocletTag createDocletTag(
         String tag, String text, 
         JavaAnnotatedElement context, int lineNumber
@@ -36,6 +37,7 @@ public class DefaultDocletTagFactory implements DocletTagFactory {
         return new DefaultDocletTag(tag, text, context, lineNumber);
     }
 
+    /** {@inheritDoc} */
     public DocletTag createDocletTag(String tag, String text) {
         return createDocletTag(tag, text, null, 0);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaAnnotation.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaAnnotation.java
index 4927f18..0c823d4 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaAnnotation.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaAnnotation.java
@@ -25,7 +25,6 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import com.thoughtworks.qdox.model.JavaAnnotatedElement;
 import com.thoughtworks.qdox.model.JavaAnnotation;
 import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.expression.AnnotationValue;
@@ -34,13 +33,11 @@ import com.thoughtworks.qdox.model.expression.ExpressionVisitor;
 /**
  * @author Eric Redmond
  */
-public class DefaultJavaAnnotation
+public class DefaultJavaAnnotation extends AbstractJavaModel
     implements AnnotationValue, Serializable, JavaAnnotation
 {
     private final JavaClass type;
 
-    private final int lineNumber;
-
     /**
      * Annotation properties as AnnotationValues
      * <p>
@@ -54,15 +51,9 @@ public class DefaultJavaAnnotation
      */
     private final Map<String, Object> namedParameters = new LinkedHashMap<String, Object>();
 
-    private JavaAnnotatedElement context;
-
-    public DefaultJavaAnnotation( JavaClass type, JavaAnnotatedElement context, Map<String, Object> namedParameters,
-                                  int lineNumber )
+    public DefaultJavaAnnotation( JavaClass type, Map<String, Object> namedParameters )
     {
         this.type = type;
-        this.context = context;
-        this.lineNumber = lineNumber;
-
         if ( properties != null )
         {
             for ( Entry<String, AnnotationValue> entry : properties.entrySet() )
@@ -75,9 +66,9 @@ public class DefaultJavaAnnotation
         }
     }
 
-    public DefaultJavaAnnotation( JavaClass type, int line )
+    public DefaultJavaAnnotation( JavaClass type )
     {
-        this( type, null, null, line );
+        this( type, null );
     }
 
     public final void setProperty( String name, AnnotationValue value )
@@ -105,17 +96,12 @@ public class DefaultJavaAnnotation
     }
 
     /** {@inheritDoc} */
-    public final JavaAnnotatedElement getContext()
+    public String getCodeBlock()
     {
-        return context;
+        return getModelWriter().writeAnnotation( this ).toString();
     }
-
+    
     /** {@inheritDoc} */
-    public int getLineNumber()
-    {
-        return lineNumber;
-    }
-
     public Object accept( ExpressionVisitor visitor )
     {
         return visitor.visit( this );
@@ -139,11 +125,7 @@ public class DefaultJavaAnnotation
         return properties.get( name );
     }
 
-    public void setContext( JavaAnnotatedElement context )
-    {
-        this.context = context;
-    }
-
+    @Override
     public String toString()
     {
         StringBuilder result = new StringBuilder();
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaClass.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaClass.java
index bfac09d..2ff5b7b 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaClass.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaClass.java
@@ -163,9 +163,7 @@ public class DefaultJavaClass
         return result;
     }
 
-    /**
-     * Shorthand for getSuperClass().getJavaClass() with null checking.
-     */
+    /** {@inheritDoc} */
     public JavaClass getSuperJavaClass()
     {
         JavaClass result = null;
@@ -184,12 +182,6 @@ public class DefaultJavaClass
     }
 
     /** {@inheritDoc} */
-    public List<JavaClass> getImplementedInterfaces()
-    {
-        return new LinkedList<JavaClass>( implementz );
-    }
-
-    /** {@inheritDoc} */
     public List<JavaClass> getInterfaces()
     {
         return new LinkedList<JavaClass>( implementz );
@@ -259,7 +251,7 @@ public class DefaultJavaClass
     /**
      * Only used when constructing the model by hand / without source
      * 
-     * @param javaPackage
+     * @param javaPackage the package
      */
     public void setJavaPackage( JavaPackage javaPackage )
     {
@@ -269,7 +261,7 @@ public class DefaultJavaClass
     /** {@inheritDoc} */
     public JavaSource getParentSource()
     {
-        return ( getParentClass() != null ? getParentClass().getParentSource() : super.getSource() );
+        return ( getDeclaringClass() != null ? getDeclaringClass().getParentSource() : super.getSource() );
     }
 
     /** {@inheritDoc} */
@@ -285,17 +277,6 @@ public class DefaultJavaClass
     }
 
     /** {@inheritDoc} */
-    public JavaClassParent getParent()
-    {
-        JavaClassParent result = getParentClass();
-        if ( result == null )
-        {
-            result = getParentSource();
-        }
-        return result;
-    }
-
-    /** {@inheritDoc} */
     public String getPackageName()
     {
         JavaPackage pckg = getPackage();
@@ -303,11 +284,31 @@ public class DefaultJavaClass
     }
 
     /** {@inheritDoc} */
+    public String getSimpleName()
+    {
+        return getName();
+    }
+    
+    /** {@inheritDoc} */
+    public String getBinaryName()
+    {
+        return ( getDeclaringClass() == null ? getCanonicalName() : getDeclaringClass().getBinaryName() + '$' + getSimpleName() ); 
+    }
+    
+    /** {@inheritDoc} */
     public String getFullyQualifiedName()
     {
-        return ( getParentClass() != null ? ( getParentClass().getClassNamePrefix() )
-                        : getPackage() != null ? ( getPackage().getName() + "." ) : "" )
-            + getName();
+        if(isPrimitive())
+        {
+            return getName();
+        }
+        else if ( getDeclaringClass() == null )
+        {
+            return (getPackage() == null ? "" :  getPackage().getName() + '.') +getSimpleName(); 
+        }
+        else {
+            return getDeclaringClass().getFullyQualifiedName() + "." + getSimpleName();
+        }
     }
 
     /** {@inheritDoc} */
@@ -343,66 +344,10 @@ public class DefaultJavaClass
     /** {@inheritDoc} */
     public boolean isInner()
     {
-        return getParentClass() != null;
-    }
-
-    /** {@inheritDoc} */
-    public String resolveType( String typeName )
-    {
-        String result;
-        JavaClass resolvedClass = getNestedClassByName( typeName );
-        if ( resolvedClass != null )
-        {
-            result = resolvedClass.getFullyQualifiedName();
-        }
-        else
-        {
-            result = getParent().resolveType( typeName );
-        }
-        return result;
-    }
-
-    /** {@inheritDoc} */
-    public String resolveCanonicalName( String name )
-    {
-        // Maybe it's an inner class?
-        for ( JavaClass innerClass : getNestedClasses() )
-        {
-            if ( innerClass.getName().equals( name ) )
-            {
-                return innerClass.getName();
-            }
-        }
-        return getParent().resolveCanonicalName( name );
-    }
-
-    /** {@inheritDoc} */
-    public String resolveFullyQualifiedName( String name )
-    {
-        // Maybe it's an inner class?
-        for ( JavaClass innerClass : getNestedClasses() )
-        {
-            if ( innerClass.getName().equals( name ) )
-            {
-                return innerClass.getFullyQualifiedName();
-            }
-        }
-        return getParent().resolveFullyQualifiedName( name );
-    }
-
-    /** {@inheritDoc} */
-    public String getClassNamePrefix()
-    {
-        return getFullyQualifiedName() + "$";
+        return getDeclaringClass() != null;
     }
 
     /** {@inheritDoc} */
-    public JavaType asType()
-    {
-        return this;
-    }
-    
-    /** {@inheritDoc} */
     public List<JavaInitializer> getInitializers()
     {
         return initializers;
@@ -492,7 +437,7 @@ public class DefaultJavaClass
 
         }
 
-        for ( JavaClass clazz : callingClazz.getImplementedInterfaces() )
+        for ( JavaClass clazz : callingClazz.getInterfaces() )
         {
             Map<String, JavaMethod> interfaceMethods = getMethodsFromSuperclassAndInterfaces( callingClazz, clazz );
             for ( Map.Entry<String, JavaMethod> methodEntry : interfaceMethods.entrySet() )
@@ -585,7 +530,7 @@ public class DefaultJavaClass
                 }
             }
 
-            for ( JavaClass clazz : getImplementedInterfaces() )
+            for ( JavaClass clazz : getInterfaces() )
             {
                 JavaMethod method = clazz.getMethodBySignature( name, parameterTypes, true, varArg );
                 if ( method != null )
@@ -651,14 +596,6 @@ public class DefaultJavaClass
         classes.add( cls );
     }
 
-    /**
-     * @deprecated Use {@link #getNestedClasses()} instead.
-     */
-    public List<JavaClass> getClasses()
-    {
-        return getNestedClasses();
-    }
-
     /** {@inheritDoc} */
     public List<JavaClass> getNestedClasses()
     {
@@ -666,20 +603,9 @@ public class DefaultJavaClass
     }
 
     /** {@inheritDoc} */
-    public JavaClass getInnerClassByName( String name )
-    {
-        return getNestedClassByName( name );
-    }
-
-    /** {@inheritDoc} */
-    public List<JavaClass> getInnerClasses()
-    {
-        return getNestedClasses();
-    }
-
-    /** {@inheritDoc} */
     public JavaClass getNestedClassByName( String name )
     {
+        
         int separatorIndex = name.indexOf( '.' );
         String directInnerClassName = ( separatorIndex > 0 ? name.substring( 0, separatorIndex ) : name );
         for ( JavaClass jClass : getNestedClasses() )
@@ -710,7 +636,7 @@ public class DefaultJavaClass
         {
             return true;
         }
-        for ( JavaClass implementz : getImplementedInterfaces() )
+        for ( JavaClass implementz : getInterfaces() )
         {
             if ( implementz.isA( fullClassName ) )
             {
@@ -739,7 +665,7 @@ public class DefaultJavaClass
         else if ( javaClass != null )
         {
             // ask our interfaces
-            for ( JavaClass intrfc : getImplementedInterfaces() )
+            for ( JavaClass intrfc : getInterfaces() )
             {
                 if ( intrfc.isA( javaClass ) )
                 {
@@ -840,12 +766,6 @@ public class DefaultJavaClass
     }
 
     /** {@inheritDoc} */
-    public JavaClass getDeclaringClass()
-    {
-        return getParentClass();
-    }
-
-    /** {@inheritDoc} */
     public List<DocletTag> getTagsByName( String name, boolean superclasses )
     {
         return getTagsRecursive( this, name, superclasses );
@@ -864,7 +784,7 @@ public class DefaultJavaClass
                 result.addAll( getTagsRecursive( superclass, name, superclasses ) );
             }
 
-            for ( JavaClass intrfc : javaClass.getImplementedInterfaces() )
+            for ( JavaClass intrfc : javaClass.getInterfaces() )
             {
                 if ( intrfc != null )
                 {
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaConstructor.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaConstructor.java
index 94486e5..2f21321 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaConstructor.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaConstructor.java
@@ -16,7 +16,7 @@ import com.thoughtworks.qdox.model.JavaTypeVariable;
  * @since 2.0
  */
 public class DefaultJavaConstructor
-    extends AbstractBaseMethod implements JavaConstructor
+    extends DefaultJavaExecutable implements JavaConstructor
 {
 
     private List<JavaTypeVariable<JavaConstructor>> typeParameters = Collections.emptyList();
@@ -32,11 +32,13 @@ public class DefaultJavaConstructor
         return typeParameters;
     }
     
+    /** {@inheritDoc} */
     public boolean signatureMatches( List<JavaType> parameterTypes )
     {
         return signatureMatches( parameterTypes, false );
     }
     
+    /** {@inheritDoc} */
     public boolean signatureMatches( List<JavaType> parameterTypes, boolean varArgs )
     {
         return super.signatureMatches( parameterTypes, varArgs );
@@ -64,9 +66,9 @@ public class DefaultJavaConstructor
         {
             result.append( "public " );
         }
-        if ( getParentClass() != null )
+        if ( getDeclaringClass() != null )
         {
-            result.append( getParentClass().getFullyQualifiedName() );
+            result.append( getDeclaringClass().getFullyQualifiedName() );
         }
         result.append( "(" );
         for ( Iterator<JavaParameter> paramIter = getParameters().iterator(); paramIter.hasNext();)
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/AbstractBaseMethod.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaExecutable.java
similarity index 87%
rename from src/main/java/com/thoughtworks/qdox/model/impl/AbstractBaseMethod.java
rename to src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaExecutable.java
index 88610c4..c67a108 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/AbstractBaseMethod.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaExecutable.java
@@ -6,6 +6,7 @@ import java.util.List;
 
 import com.thoughtworks.qdox.model.DocletTag;
 import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaExecutable;
 import com.thoughtworks.qdox.model.JavaMethod;
 import com.thoughtworks.qdox.model.JavaParameter;
 import com.thoughtworks.qdox.model.JavaType;
@@ -16,8 +17,8 @@ import com.thoughtworks.qdox.model.JavaType;
  * @author Robert Scholte
  *
  */
-public abstract class AbstractBaseMethod
-    extends AbstractInheritableJavaEntity
+public abstract class DefaultJavaExecutable 
+    extends AbstractInheritableJavaEntity implements JavaExecutable
 {
 
     private List<JavaParameter> parameters = Collections.emptyList();
@@ -25,11 +26,13 @@ public abstract class AbstractBaseMethod
     private boolean varArgs;
     private String sourceCode;
 
+    /** {@inheritDoc} */
     public List<JavaParameter> getParameters()
     {
         return parameters;
     }
 
+    /** {@inheritDoc} */
     public JavaParameter getParameterByName( String name )
     {
         for (JavaParameter parameter : getParameters()) {
@@ -40,26 +43,24 @@ public abstract class AbstractBaseMethod
         return null;
     }
 
+    /** {@inheritDoc} */
     public List<JavaClass> getExceptions()
     {
         return new LinkedList<JavaClass>( exceptions );
     }
-    
+
+    /** {@inheritDoc} */
     public List<JavaType> getExceptionTypes()
     {
         return new LinkedList<JavaType>( exceptions );
     }
 
+    /** {@inheritDoc} */
     public boolean isVarArgs()
     {
         return varArgs;
     }
 
-    public JavaClass getDeclaringClass()
-    {
-        return getParentClass();
-    }
-
     public void setParameters( List<JavaParameter> javaParameters )
     {
         parameters = javaParameters;
@@ -95,14 +96,16 @@ public abstract class AbstractBaseMethod
         return (this.varArgs == varArgs);
     }
 
+    /** {@inheritDoc} */
     public boolean isPublic()
     {
-        return super.isPublic() || (getParentClass() != null ? getParentClass().isInterface() : false);
+        return super.isPublic() || (getDeclaringClass() != null ? getDeclaringClass().isInterface() : false);
     }
 
+    /** {@inheritDoc} */
     public List<DocletTag> getTagsByName( String name, boolean inherited )
     {
-        JavaClass cls = getParentClass();
+        JavaClass cls = getDeclaringClass();
         List<JavaType> types = new LinkedList<JavaType>();
         for (JavaParameter parameter : getParameters()) {
             types.add(parameter.getType());
@@ -121,6 +124,7 @@ public abstract class AbstractBaseMethod
         return result;
     }
 
+    /** {@inheritDoc} */
     public List<JavaType> getParameterTypes()
     {
         return getParameterTypes( false );
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaField.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaField.java
index a84aea5..40a3f2a 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaField.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaField.java
@@ -29,7 +29,6 @@ public class DefaultJavaField
     extends AbstractJavaEntity
     implements JavaField
 {
-
     private JavaClass type;
 
     private String initializationExpression;
@@ -40,10 +39,6 @@ public class DefaultJavaField
     
     private List<Expression> enumConstantArguments;
 
-    public DefaultJavaField()
-    {
-    }
-
     public DefaultJavaField( String name )
     {
         setName( name );
@@ -56,12 +51,6 @@ public class DefaultJavaField
     }
 
     /** {@inheritDoc} */
-    public JavaClass getDeclaringClass()
-    {
-        return getParentClass();
-    }
-
-    /** {@inheritDoc} */
     public JavaClass getType()
     {
         return type;
@@ -79,30 +68,6 @@ public class DefaultJavaField
     }
 
     /** {@inheritDoc} */
-    public String getDeclarationSignature( boolean withModifiers )
-    {
-        StringBuilder result = new StringBuilder();
-        if ( withModifiers )
-        {
-            for ( String modifier : getModifiers() )
-            {
-                result.append( modifier );
-                result.append( ' ' );
-            }
-        }
-        result.append( type.getCanonicalName() );
-        result.append( ' ' );
-        result.append( getName() );
-        return result.toString();
-    }
-
-    /** {@inheritDoc} */
-    public String getCallSignature()
-    {
-        return getName();
-    }
-
-    /** {@inheritDoc} */
     public String getInitializationExpression()
     {
         return initializationExpression;
@@ -164,6 +129,7 @@ public class DefaultJavaField
         {
             result.append( "public " );
         }
+        
         if ( isStatic() )
         {
             result.append( "static " );
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaInitializer.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaInitializer.java
index 818c18f..927f7a4 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaInitializer.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaInitializer.java
@@ -32,6 +32,7 @@ public class DefaultJavaInitializer extends AbstractJavaModel implements JavaIni
     
     private String blockContent;
 
+    /** {@inheritDoc} */
     public boolean isStatic()
     {
         return staticInitializer;
@@ -42,6 +43,7 @@ public class DefaultJavaInitializer extends AbstractJavaModel implements JavaIni
         this.staticInitializer = staticInitializer;
     }
 
+    /** {@inheritDoc} */
     public String getBlockContent()
     {
         return blockContent;
@@ -52,6 +54,7 @@ public class DefaultJavaInitializer extends AbstractJavaModel implements JavaIni
         this.blockContent = codeBlock;
     }
     
+    /** {@inheritDoc} */
     public String getCodeBlock()
     {
         return getModelWriter().writeInitializer( this ).toString();
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaMethod.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaMethod.java
index 378b85e..595cc51 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaMethod.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaMethod.java
@@ -31,10 +31,10 @@ import com.thoughtworks.qdox.model.JavaParameter;
 import com.thoughtworks.qdox.model.JavaType;
 import com.thoughtworks.qdox.model.JavaTypeVariable;
 
-public class DefaultJavaMethod extends AbstractBaseMethod implements JavaMethod {
+public class DefaultJavaMethod extends DefaultJavaExecutable implements JavaMethod {
 
     private boolean defaultMethod;
-	private JavaClass returns = DefaultJavaType.VOID;
+	private JavaClass returns;
     private List<JavaTypeVariable<JavaMethod>> typeParameters = Collections.emptyList();
 	
     /**
@@ -124,7 +124,7 @@ public class DefaultJavaMethod extends AbstractBaseMethod implements JavaMethod
 
         if ( isDeclaration )
         {
-            result.append( returns.getCanonicalName() );
+            result.append( returns.getGenericCanonicalName() );
             result.append( ' ' );
         }
 
@@ -135,7 +135,7 @@ public class DefaultJavaMethod extends AbstractBaseMethod implements JavaMethod
             JavaParameter parameter = iter.next();
             if ( isDeclaration )
             {
-                result.append( parameter.getType().getCanonicalName() );
+                result.append( parameter.getType().getGenericCanonicalName() );
                 if ( parameter.isVarArgs() )
                 {
                     result.append( "..." );
@@ -154,7 +154,7 @@ public class DefaultJavaMethod extends AbstractBaseMethod implements JavaMethod
             result.append( " throws " );
             for ( Iterator<JavaClass> excIter = getExceptions().iterator(); excIter.hasNext(); )
             {
-                result.append( excIter.next().getCanonicalName() );
+                result.append( excIter.next().getGenericCanonicalName() );
                 if ( excIter.hasNext() )
                 {
                     result.append( ", " );
@@ -328,7 +328,7 @@ public class DefaultJavaMethod extends AbstractBaseMethod implements JavaMethod
         return Introspector.decapitalize( getName().substring( start ) );
     }
 
-    /** {@inheritDoc} */
+    @Override
     public String toString()
     {
         StringBuilder result = new StringBuilder();
@@ -365,9 +365,9 @@ public class DefaultJavaMethod extends AbstractBaseMethod implements JavaMethod
             result.append( "native " );
         }
         result.append( getReturns().getFullyQualifiedName() ).append( ' ' );
-        if ( getParentClass() != null )
+        if ( getDeclaringClass() != null )
         {
-            result.append( getParentClass().getFullyQualifiedName() );
+            result.append( getDeclaringClass().getBinaryName() );
             result.append( "." );
         }
         result.append( getName() );
@@ -399,12 +399,6 @@ public class DefaultJavaMethod extends AbstractBaseMethod implements JavaMethod
     }
 
     /** {@inheritDoc} */
-    public JavaClass getGenericReturnType()
-    {
-        return returns;
-    }
-
-    /** {@inheritDoc} */
     public JavaType getReturnType()
     {
         return getReturnType( false );
@@ -415,12 +409,14 @@ public class DefaultJavaMethod extends AbstractBaseMethod implements JavaMethod
     {
         return returns;
     }
-    
+
+    /** {@inheritDoc} */
     public boolean signatureMatches( String name, List<JavaType> parameterTypes )
     {
         return signatureMatches( name, parameterTypes, false );
     }
     
+    /** {@inheritDoc} */
     public boolean signatureMatches( String name, List<JavaType> parameterTypes, boolean varArg )
     {
         if ( !name.equals( this.getName() ) ) 
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaModule.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaModule.java
new file mode 100644
index 0000000..8db85de
--- /dev/null
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaModule.java
@@ -0,0 +1,43 @@
+package com.thoughtworks.qdox.model.impl;
+
+import com.thoughtworks.qdox.model.JavaModule;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor;
+
+public class DefaultJavaModule extends AbstractJavaModel
+    implements JavaModule
+{
+    private String name;
+    
+    private JavaModuleDescriptor descriptor;
+
+    public DefaultJavaModule( String name, JavaModuleDescriptor descriptor )
+    {
+        this.name = name;
+        this.descriptor = descriptor;
+    }
+    
+    /** {@inheritDoc} */
+    public String getCodeBlock()
+    {
+        return getModelWriter().writeModuleDescriptor( this.descriptor ).toString();
+    }
+    
+    /** {@inheritDoc} */
+    public String getName()
+    {
+        return name;
+    }
+
+    /** {@inheritDoc} */
+    public boolean isNamed()
+    {
+        return name != null;
+    }
+
+    /** {@inheritDoc} */
+    public JavaModuleDescriptor getDescriptor()
+    {
+        return descriptor;
+    }
+
+}
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaModuleDescriptor.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaModuleDescriptor.java
new file mode 100644
index 0000000..d8c088c
--- /dev/null
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaModuleDescriptor.java
@@ -0,0 +1,311 @@
+package com.thoughtworks.qdox.model.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaModule;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor;
+import com.thoughtworks.qdox.model.JavaPackage;
+
+public class DefaultJavaModuleDescriptor implements JavaModuleDescriptor
+{
+    private String name; 
+
+    private boolean open;
+    
+    private Collection<DefaultJavaRequires> requires = new ArrayList<DefaultJavaRequires>();
+
+    private Collection<DefaultJavaExports> exports = new ArrayList<DefaultJavaExports>();
+
+    private Collection<DefaultJavaOpens> opens = new ArrayList<DefaultJavaOpens>();
+
+    private Collection<DefaultJavaUses> uses = new ArrayList<DefaultJavaUses>();
+
+    private Collection<DefaultJavaProvides> provides = new ArrayList<DefaultJavaProvides>();
+
+    public DefaultJavaModuleDescriptor( String name )
+    {
+        this.name = name;
+    }
+
+    /** {@inheritDoc} */
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setOpen( boolean open )
+    {
+        this.open = open;
+    }
+
+    /** {@inheritDoc} */
+    public boolean isOpen()
+    {
+        return open;
+    }
+    
+    public void addExports( DefaultJavaExports exports )
+    {
+        this.exports.add( exports );
+    }
+
+    /** {@inheritDoc} */
+    public Collection<JavaExports> getExports()
+    {
+        return Collections.<JavaExports>unmodifiableCollection( exports );
+    } 
+
+    public void addOpens( DefaultJavaOpens opens )
+    {
+        this.opens.add( opens );
+    }
+
+    /** {@inheritDoc} */
+    public Collection<JavaOpens> getOpens()
+    {
+        return Collections.<JavaOpens>unmodifiableCollection( opens );
+    } 
+    
+    public void addRequires( DefaultJavaRequires requires )
+    {
+        this.requires.add( requires );
+    }
+
+    /** {@inheritDoc} */
+    public Collection<JavaRequires> getRequires()
+    {
+        return Collections.<JavaRequires>unmodifiableCollection( requires );
+    }
+
+    public void addProvides( DefaultJavaProvides provides )
+    {
+        this.provides.add( provides);
+    }
+
+    /** {@inheritDoc} */
+    public Collection<JavaProvides> getProvides()
+    {
+        return Collections.<JavaProvides>unmodifiableCollection( provides );
+    }
+
+    public void addUses( DefaultJavaUses uses)
+    {
+        this.uses.add( uses );
+    }
+
+    /** {@inheritDoc} */
+    public Collection<JavaUses> getUses()
+    {
+        return Collections.<JavaUses>unmodifiableCollection( uses );
+    } 
+
+    public static class DefaultJavaExports extends AbstractJavaModel implements JavaModuleDescriptor.JavaExports
+    {
+        private JavaPackage source;
+
+        private Collection<JavaModule> targets;
+
+        public DefaultJavaExports( JavaPackage source, Collection<JavaModule> targets )
+        {
+            this.source = source;
+            this.targets = targets;
+        }
+
+        /** {@inheritDoc} */
+        public JavaPackage getSource()
+        {
+            return source;
+        }
+
+        /** {@inheritDoc} */
+        public Collection<JavaModule> getTargets()
+        {
+            if( targets == null )
+            {
+                return Collections.emptyList();
+            }
+            else
+            {
+                return targets;
+            }
+        }
+
+        /** {@inheritDoc} */
+        public String getCodeBlock()
+        {
+            return getModelWriter().writeModuleExports( this ).toString();
+        }
+    }
+    
+    public static class DefaultJavaOpens extends AbstractJavaModel implements JavaModuleDescriptor.JavaOpens
+    {
+        private JavaPackage source;
+
+        private Collection<JavaModule> targets;
+
+        public DefaultJavaOpens( JavaPackage source, Collection<JavaModule> targets )
+        {
+            this.source = source;
+            this.targets = targets;
+        }
+
+        public String source()
+        {
+            return source.getName();
+        }
+
+        /** {@inheritDoc} */
+        public JavaPackage getSource()
+        {
+            return source;
+        }
+
+        /** {@inheritDoc} */
+        public Collection<JavaModule> getTargets()
+        {
+            if( targets == null )
+            {
+                return Collections.emptyList();
+            }
+            else
+            {
+                return targets;
+            }
+        }
+        
+        public Set<String> targets()
+        {
+            if( targets == null )
+            {
+                return Collections.emptySet();
+            }
+            else
+            {
+                Set<String> targetValues = new LinkedHashSet<String>( targets.size() );
+                
+                for ( JavaModule target : targets )
+                {
+                    targetValues.add( target.getName() );
+                }
+                
+                return Collections.unmodifiableSet( targetValues );
+            }
+        }
+
+        /** {@inheritDoc} */
+        public String getCodeBlock()
+        {
+            return getModelWriter().writeModuleOpens( this ).toString();
+        }
+    }
+    
+    public static class DefaultJavaProvides extends AbstractJavaModel implements JavaModuleDescriptor.JavaProvides
+    {
+        private JavaClass service;
+        
+        private List<JavaClass> providers;
+
+        public DefaultJavaProvides( JavaClass service, List<JavaClass> providers )
+        {
+            super();
+            this.service = service;
+            this.providers = providers;
+        }
+
+        /** {@inheritDoc} */
+        public JavaClass getService()
+        {
+            return service;
+        }
+
+        /** {@inheritDoc} */
+        public List<JavaClass> getProviders()
+        {
+            return providers;
+        }
+
+        /** {@inheritDoc} */
+        public String getCodeBlock()
+        {
+            return getModelWriter().writeModuleProvides( this ).toString();
+        }
+    }
+    
+    public static class DefaultJavaRequires extends AbstractJavaModel implements JavaModuleDescriptor.JavaRequires 
+    {
+        private JavaModule module;
+        
+        private Collection<String> modifiers;
+    
+        public DefaultJavaRequires( JavaModule module, Collection<String> modifiers )
+        {
+            this.module = module;
+            this.modifiers = modifiers;
+        }
+
+        /** {@inheritDoc} */
+        public JavaModule getModule()
+        {
+            return module;
+        }
+
+        /** {@inheritDoc} */
+        public boolean isTransitive()
+        {
+            return getModifiers().contains( "transitive" );
+        }
+
+        /** {@inheritDoc} */
+        public boolean isStatic()
+        {
+            return getModifiers().contains( "static" );
+        }
+
+        /** {@inheritDoc} */
+        public Collection<String> getModifiers()
+        {
+            if( modifiers == null )
+            {
+                return Collections.emptyList();
+            }
+            else
+            {
+                return modifiers;
+            }
+        }
+
+        /** {@inheritDoc} */
+        public String getCodeBlock()
+        {
+            return getModelWriter().writeModuleRequires( this ).toString();
+        }
+    }
+    
+    public static class DefaultJavaUses extends AbstractJavaModel implements JavaModuleDescriptor.JavaUses
+    {
+        private JavaClass service;
+
+        public DefaultJavaUses( JavaClass service )
+        {
+            this.service = service;
+        }
+
+        /** {@inheritDoc} */
+        public JavaClass getService()
+        {
+            return service;
+        }
+
+        /** {@inheritDoc} */
+        public String getCodeBlock()
+        {
+            return getModelWriter().writeModuleUses( this ).toString();
+        }
+    }
+}
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameter.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameter.java
index 896131f..f0dc2ea 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameter.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameter.java
@@ -1,10 +1,9 @@
 package com.thoughtworks.qdox.model.impl;
 
 import com.thoughtworks.qdox.model.JavaClass;
-import com.thoughtworks.qdox.model.JavaMethod;
 import com.thoughtworks.qdox.model.JavaParameter;
 import com.thoughtworks.qdox.model.JavaType;
-import com.thoughtworks.qdox.model.ParameterDeclarator;
+import com.thoughtworks.qdox.model.JavaExecutable;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,7 +30,7 @@ public class DefaultJavaParameter extends AbstractBaseJavaEntity implements Java
 
     private String name;
     private JavaClass type;
-    private ParameterDeclarator declarator;
+    private JavaExecutable executable;
     private boolean varArgs;
 
     public DefaultJavaParameter( JavaClass type, String name )
@@ -76,26 +75,32 @@ public class DefaultJavaParameter extends AbstractBaseJavaEntity implements Java
     }
 
     /** {@inheritDoc} */
-    public ParameterDeclarator getDeclarator()
+    public JavaExecutable getExecutable()
     {
-        return declarator;
+        return executable;
     }
 
-    public void setDeclarator( ParameterDeclarator declarator )
+    public void setExecutable( JavaExecutable executable )
     {
-        this.declarator = declarator;
+        this.executable = executable;
     }
     
     /** {@inheritDoc} */
-    public JavaClass getParentClass()
+    public JavaClass getDeclaringClass()
     {
-        return getDeclarator().getParentClass();
+        return getExecutable().getDeclaringClass();
     }
 
     /** {@inheritDoc} */
     public boolean isVarArgs() {
         return varArgs;
     }
+    
+    /** {@inheritDoc} */
+    public String getBinaryName()
+    {
+        return type.getBinaryName();
+    }
 
     /** {@inheritDoc} */
     public String getFullyQualifiedName()
@@ -130,25 +135,25 @@ public class DefaultJavaParameter extends AbstractBaseJavaEntity implements Java
     /** {@inheritDoc} */
     public String getResolvedValue()
     {
-        return DefaultJavaType.getResolvedValue( type, getDeclarator().getTypeParameters() );
+        return DefaultJavaType.getResolvedValue( type, getExecutable().getTypeParameters() );
     }
 
     /** {@inheritDoc} */
     public String getResolvedFullyQualifiedName() 
     {
-        return DefaultJavaType.getResolvedFullyQualifiedName( type, getDeclarator().getTypeParameters() );
+        return DefaultJavaType.getResolvedFullyQualifiedName( type, getExecutable().getTypeParameters() );
     }
     
     /** {@inheritDoc} */
 	public String getResolvedGenericValue() 
 	{
-		return DefaultJavaType.getResolvedGenericValue( type, getDeclarator().getTypeParameters() );
+		return DefaultJavaType.getResolvedGenericValue( type, getExecutable().getTypeParameters() );
 	}
 	
     /** {@inheritDoc} */
 	public String getResolvedGenericFullyQualifiedName()
 	{
-	    return DefaultJavaType.getResolvedGenericFullyQualifiedName( type, getDeclarator().getTypeParameters() );
+	    return DefaultJavaType.getResolvedGenericFullyQualifiedName( type, getExecutable().getTypeParameters() );
 	}
 
     @Override
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterizedType.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterizedType.java
index 855a8e1..e3451de 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterizedType.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterizedType.java
@@ -25,41 +25,19 @@ import java.util.List;
 
 import com.thoughtworks.qdox.model.JavaParameterizedType;
 import com.thoughtworks.qdox.model.JavaType;
+import com.thoughtworks.qdox.type.TypeResolver;
 
 public class DefaultJavaParameterizedType extends DefaultJavaType implements JavaParameterizedType
 {
     private List<JavaType> actualArgumentTypes = Collections.emptyList();
 
-    
-    public DefaultJavaParameterizedType( String fullName, int dimensions, JavaClassParent context )
+    public DefaultJavaParameterizedType( String fullName, String name, int dimensions, TypeResolver typeResolver )
     {
-        super( fullName, dimensions, context );
+        super( fullName, name, dimensions, typeResolver );
     }
 
-    public DefaultJavaParameterizedType( String fullName, int dimensions )
-    {
-        super( fullName, dimensions );
-    }
 
-    public DefaultJavaParameterizedType( String name, JavaClassParent context )
-    {
-        super( name, context );
-    }
-
-    public DefaultJavaParameterizedType( String fullName, String name, int dimensions, JavaClassParent context )
-    {
-        super( fullName, name, dimensions, context );
-    }
-
-    public DefaultJavaParameterizedType( String fullName )
-    {
-        super( fullName );
-    }
-
-    /**
-     * 
-     * @return the actualTypeArguments or null
-     */
+    /** {@inheritDoc} */
     public List<JavaType> getActualTypeArguments()
     {
         return actualArgumentTypes;
@@ -70,25 +48,10 @@ public class DefaultJavaParameterizedType extends DefaultJavaType implements Jav
         this.actualArgumentTypes = actualArgumentTypes;
     }
     
-    /**
-     * The FQN representation of an Object for code usage
-     * This implementation ignores generics
-     *
-     * Some examples how Objects will be translated
-     * <pre>
-     * Object > java.lang.object
-     * java.util.List<T> > java.util.List
-     * ? > ?
-     * T > T
-     * anypackage.Outer.Inner > anypackage.Outer.Inner
-     * </pre>
-
-     * @since 1.8
-     * @return generic type representation for code usage 
-     */
+    /** {@inheritDoc} */
     public String getGenericValue()
     {
-        StringBuilder result = new StringBuilder( getValue() );
+        StringBuilder result = new StringBuilder( name );
         if ( !actualArgumentTypes.isEmpty() )
         {
             result.append( "<" );
@@ -109,9 +72,11 @@ public class DefaultJavaParameterizedType extends DefaultJavaType implements Jav
         return result.toString();
     }
     
+    /** {@inheritDoc} */
     public String getGenericCanonicalName()
     {
-        StringBuilder result = new StringBuilder( getCanonicalName() );
+        String base = isArray() ? getComponentType().getCanonicalName() : getCanonicalName();
+        StringBuilder result = new StringBuilder( base );
         if ( !actualArgumentTypes.isEmpty() )
         {
             result.append( "<" );
@@ -132,6 +97,7 @@ public class DefaultJavaParameterizedType extends DefaultJavaType implements Jav
         return result.toString();
     }
 
+    /** {@inheritDoc} */
     public String getGenericFullyQualifiedName()
     {
         StringBuilder result = new StringBuilder( isResolved() ? fullName : name );
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaSource.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaSource.java
index f66a31a..86208e4 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaSource.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaSource.java
@@ -22,12 +22,8 @@ package com.thoughtworks.qdox.model.impl;
 import java.io.Serializable;
 import java.net.URL;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 import com.thoughtworks.qdox.library.ClassLibrary;
 import com.thoughtworks.qdox.model.JavaClass;
@@ -40,27 +36,12 @@ import com.thoughtworks.qdox.writer.impl.DefaultModelWriter;
 
 public class DefaultJavaSource implements JavaSource, Serializable {
 
-    private static final Set<String> PRIMITIVE_TYPES = new HashSet<String>();
-
-    static {
-        PRIMITIVE_TYPES.add("boolean");
-        PRIMITIVE_TYPES.add("byte");
-        PRIMITIVE_TYPES.add("char");
-        PRIMITIVE_TYPES.add("double");
-        PRIMITIVE_TYPES.add("float");
-        PRIMITIVE_TYPES.add("int");
-        PRIMITIVE_TYPES.add("long");
-        PRIMITIVE_TYPES.add("short");
-        PRIMITIVE_TYPES.add("void");
-    }
-
     private final ClassLibrary classLibrary;
     private ModelWriterFactory modelWriterFactory;
     
     private JavaPackage pkg;
-    private List<String> imports = new LinkedList<String>();
+    private final List<String> imports = new LinkedList<String>();
     private List<JavaClass> classes = new LinkedList<JavaClass>();
-    private Map<String, String> resolvedTypeCache = new HashMap<String, String>();
     private URL url;
 
     /**
@@ -74,6 +55,7 @@ public class DefaultJavaSource implements JavaSource, Serializable {
     }
 
     /**
+     * @param url the URL of the source file
      * @since 1.4
      */
     public void setURL(URL url) {
@@ -117,206 +99,16 @@ public class DefaultJavaSource implements JavaSource, Serializable {
         return getModelWriter().writeSource( this ).toString();
     }
     
-    /** {@inheritDoc} */
+    @Override
     public String toString() {
     	return getCodeBlock();
     }
 
     /**  {@inheritDoc} */
-    public String resolveType( String typeName )
-    {
-        return resolveFullyQualifiedName( typeName );
-    }
-    
-    /**  {@inheritDoc} */
-   public String resolveFullyQualifiedName( String name )
-    {
-        String result = resolvedTypeCache.get( name );
-        if ( result == null )
-        {
-            result = resolveTypeInternal( name );
-            if ( result != null )
-            {
-                resolvedTypeCache.put( name, result );
-            }
-        }
-        return result;
-    }
-    
-    /**  {@inheritDoc} */
-    public String resolveCanonicalName( String name )
-    {
-        String className = resolveFullyQualifiedName( name );
-        String result = null;
-        if ( className != null )
-        {
-            result = className.replace( '$', '.' );
-        }
-        return result;
-    }
-    
-    /**
-     * Resolves a type name
-     * <p>
-     * Follows the <a href="http://java.sun.com/docs/books/jls/third_edition/html/packages.html#7.5.1">
-     * Java Language Specification, Version 3.0</a>.
-     * <p>
-     * Current resolution order is:
-     * <ol>
-     * <li>Single-Type-Import Declaration</li>
-     * <li>Type-Import-on-Demand Declaration</li>
-     * <li>Automatic Imports</li>
-     * </ol>
-     * 
-     * @param typeName the name to resolve
-     * @return the resolved type name, otherwise <code>null</code>
-     */
-    private String resolveTypeInternal( String typeName )
-    {
-        String resolvedName = null;
-
-        lookup:
-        {
-            // primitive types
-            if ( PRIMITIVE_TYPES.contains( typeName ) )
-            {
-                resolvedName = typeName;
-                break lookup;
-            }
-
-            String outerName = typeName;
-            String nestedName = typeName.replace( '.', '$' );
-            int dotpos = typeName.indexOf( '.' );
-
-            if ( dotpos >= 0 )
-            {
-                outerName = typeName.substring( 0, dotpos );
-            }
-
-            // Check single-type-import with fully qualified name
-            resolvedName = resolveImportedType( typeName, nestedName, true );
-
-            if ( resolvedName != null )
-            {
-                break lookup;
-            }
-
-            // Check single-type-import with outer name
-            resolvedName = resolveImportedType( outerName, nestedName, false );
-
-            if ( resolvedName != null )
-            {
-                break lookup;
-            }
-
-            // check for class in the same package
-            if ( getPackage() != null )
-            {
-                resolvedName = resolveFullyQualifiedType( getPackageName() + '.' + typeName );
-
-                if ( resolvedName != null )
-                {
-                    break lookup;
-                }
-            }
-
-            // check for a class globally
-            resolvedName = resolveFullyQualifiedType( typeName );
-
-            if ( resolvedName != null )
-            {
-                break lookup;
-            }
-
-            // check for a class in the same package
-            resolvedName = resolveFromLibrary( getClassNamePrefix() + nestedName );
-            if ( resolvedName != null )
-            {
-                break lookup;
-            }
-
-            // try java.lang.*
-            resolvedName = resolveFromLibrary( "java.lang." + nestedName );
-            if ( resolvedName != null )
-            {
-                break lookup;
-            }
-
-            // Check type-import-on-demand
-            resolvedName = resolveImportedType( "*", nestedName, false );
-
-            if ( resolvedName != null )
-            {
-                break lookup;
-            }
-        }
-
-        return resolvedName;
-    }
-    
-    private String resolveImportedType( String importSpec, String typeName, boolean fullMatch )
-    {
-        String resolvedName = null;
-        String dotSuffix = "." + importSpec;
-
-        for ( String imprt : getImports() )
-        {
-            // static imports can refer to inner classes
-            if ( imprt.startsWith( "static " ) )
-            {
-                imprt = imprt.substring( 7 );
-            }
-            if ( imprt.equals( importSpec ) || ( !fullMatch && imprt.endsWith( dotSuffix ) ) )
-            {
-                String candidateName = imprt.substring( 0, imprt.length() - importSpec.length() ) + typeName;
-                resolvedName = resolveFullyQualifiedType( candidateName );
-                if ( resolvedName == null && !"*".equals( importSpec ) )
-                {
-                    resolvedName = candidateName;
-                }
-                if ( resolvedName != null )
-                {
-                    break;
-                }
-            }
-        }
-
-        return resolvedName;
-    }
-    
-    private String resolveFromLibrary(String typeName) {
-        return classLibrary.hasClassReference( typeName ) ? typeName : null;
-    }
-    
-    private String resolveFullyQualifiedType(String typeName) {
-        int indexOfLastDot = typeName.lastIndexOf('.');
-        
-        if (indexOfLastDot >= 0) {
-            String root = typeName.substring(0,indexOfLastDot);
-            String leaf = typeName.substring(indexOfLastDot+1);
-            String resolvedTypeName = resolveFullyQualifiedType(root + '$' + leaf);
-            
-            if(resolvedTypeName != null) {
-                return resolvedTypeName;
-            }
-        }
-
-        if( classLibrary.hasClassReference( typeName )) 
-        {
-            return typeName;
-        }
-        return null;
-    }
-
-    /**  {@inheritDoc} */
     public String getClassNamePrefix() {
         return ( pkg == null ? "" : pkg.getName() + '.' ); 
     }
 
-    public JavaSource getParentSource() {
-        return this;
-    }
-    
     /**  {@inheritDoc} */
     public JavaClass getNestedClassByName(String name) {
         JavaClass result = null;
@@ -360,7 +152,7 @@ public class DefaultJavaSource implements JavaSource, Serializable {
     
     /**
      * 
-     * @param modelWriterFactory
+     * @param modelWriterFactory the modelWriterFactory
      * @since 2.0
      */
     public void setModelWriterFactory( ModelWriterFactory modelWriterFactory )
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaType.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaType.java
index 4ecd782..e1d3512 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaType.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaType.java
@@ -40,54 +40,77 @@ import com.thoughtworks.qdox.model.JavaParameterizedType;
 import com.thoughtworks.qdox.model.JavaSource;
 import com.thoughtworks.qdox.model.JavaType;
 import com.thoughtworks.qdox.model.JavaTypeVariable;
+import com.thoughtworks.qdox.type.TypeResolver;
 
+/**
+ * The default implementation for {@link JavaType}
+ * 
+ * @author Robert Scholte
+ * @since 2.0
+ */
 public class DefaultJavaType implements JavaClass, JavaType, Serializable {
 
-    public static final DefaultJavaType VOID = new DefaultJavaType("void");
-
     protected final String name;
-    private JavaClassParent context;
     protected String fullName;
     private int dimensions;
     
-    public DefaultJavaType( String name, JavaClassParent context )
+    private TypeResolver typeResolver;
+    
+    DefaultJavaType( String name, TypeResolver typeResolver )
     {
         this.name = name;
-        this.context = context;
+        this.typeResolver = typeResolver;
     }
-    
-    public DefaultJavaType(String fullName, String name, int dimensions, JavaClassParent context) {
+
+    DefaultJavaType(String fullName, String name, int dimensions, TypeResolver typeResolver) {
         this.fullName = fullName;
         this.name = name;
         this.dimensions = dimensions;
-        this.context = context;
-    }
-    
-    public DefaultJavaType(String fullName, int dimensions, JavaClassParent context) {
-        this(fullName, (String) null, dimensions, context);
-    }
-
-    public DefaultJavaType(String fullName, int dimensions) {
-        this(fullName, dimensions, null);
+        this.typeResolver = typeResolver;
     }
 
     /**
      * Should only be used by primitives, since they don't have a classloader.
      * 
      * @param fullName the name of the primitive
+     * @param dimensions number of dimensions
      */
-    public DefaultJavaType( String fullName ) 
+    DefaultJavaType(String fullName, int dimensions) {
+        this.name = fullName;
+        this.fullName = fullName;
+        this.dimensions = dimensions;
+    }
+
+    /**
+     * Should only be used by primitives and wildcard, since they don't have a classloader.
+     * 
+     * @param fullName the name of the primitive or ?
+     */
+    DefaultJavaType( String fullName ) 
     {
         this( fullName, 0 );
     }
     
-	public static DefaultJavaType createUnresolved(String name, int dimensions, JavaClassParent context) {
-        return new DefaultJavaType(null, name, dimensions, context);
-    }
-    
+    /** {@inheritDoc} */
+	public String getBinaryName()
+	{
+	    return resolveRealClass().getBinaryName(); 
+	}
+	
+	/** {@inheritDoc} */
+	public String getSimpleName()
+	{
+	    StringBuilder result = new StringBuilder( resolveRealClass().getSimpleName() );
+        for (int i = 0; i < dimensions; i++) 
+        {
+            result.append("[]");
+        }
+        return result.toString();
+	}
+	
     /** {@inheritDoc} */
     public String getFullyQualifiedName() {
-        StringBuilder result = new StringBuilder( isResolved() ? fullName : name );
+        StringBuilder result = new StringBuilder( resolveRealClass().getFullyQualifiedName() );
         for (int i = 0; i < dimensions; i++) 
         {
             result.append("[]");
@@ -95,37 +118,22 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
         return result.toString();
     }
 
-    /**
-     * Equivalent of {@link Class#getComponentType()}
-     * If this type is an array, return its component type
-     * 
-     * @return the type of array if it's one, otherwise <code>null</code>
-     */
+    /** {@inheritDoc}*/
     public JavaClass getComponentType() {
       return isArray() ? resolveRealClass() : null;
     }
     
     /** {@inheritDoc}*/
     public String getValue() {
-        return ( name != null ?  name : getFullyQualifiedName().replaceAll( "\\$", "." ) );
+        StringBuilder result = new StringBuilder( name );
+        for (int i = 0; i < dimensions; i++) 
+        {
+            result.append("[]");
+        }
+        return result.toString();
     }
     
-    /**
-     * The FQN representation of an Object for code usage
-     * This implementation ignores generics
-     *
-     * Some examples how Objects will be translated
-     * <pre>
-     * Object > java.lang.object
-     * java.util.List<T> > java.util.List
-     * ? > ?
-     * T > T
-     * anypackage.Outer.Inner > anypackage.Outer.Inner
-     * </pre>
-
-     * @since 1.8
-     * @return generic type representation for code usage 
-     */
+    /** {@inheritDoc}*/
     public String getGenericValue()
     {
         StringBuilder result = new StringBuilder( getValue() );
@@ -195,27 +203,19 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
 
     protected boolean isResolved()
     {
-        if ( fullName == null && context != null )
+        if ( fullName == null && typeResolver != null )
         {
-            fullName = context.resolveType( name );
+            fullName = typeResolver.resolveType( name );
         }
         return ( fullName != null );
     }
 
-    /**
-     * Returns true if this Type is an array
-     * 
-     * @return true if this type is an array, otherwise <code>null</code>
-     */
+    /** {@inheritDoc} */
     public boolean isArray() {
         return dimensions > 0;
     }
 
-    /**
-     * Returns the depth of this array, 0 if it's not an array
-     * 
-     * @return The depth of this array, at least <code>0</code>
-     */
+    /** {@inheritDoc} */
     public int getDimensions() {
         return dimensions;
     }
@@ -236,11 +236,11 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
      * Returns getGenericValue() extended with the array information
      * 
      * <pre>
-     * Object > java.lang.Object
-     * Object[] > java.lang.Object[]
-     * List<Object> > java.lang.List<java.lang.Object>
-     * Outer.Inner > Outer$Inner
-     * Outer.Inner<Object>[][] > Outer$Inner<java.lang.Object>[][] 
+     * Object > java.lang.Object
+     * Object[] > java.lang.Object[]
+     * List<Object> > java.lang.List<java.lang.Object>
+     * Outer.Inner > Outer$Inner
+     * Outer.Inner<Object>[][] > Outer$Inner<java.lang.Object>[][] 
      * </pre>
      * @return a generic string representation of this type.
      */
@@ -270,7 +270,7 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
     
     private JavaClass resolveRealClass() 
     {
-        JavaClass result;
+        JavaClass result = null;
         String qualifiedName = isResolved() ? fullName : name;
         if ( isPrimitive( qualifiedName ) )
         {
@@ -278,27 +278,14 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
         }
         else
         {
-            result = getJavaClassParent().getNestedClassByName( qualifiedName );
-            if ( result == null )
-            {
-                result = getJavaClassLibrary().getJavaClass( qualifiedName, true );
-            }
+            result = typeResolver.getJavaClass( qualifiedName );
         }
-
         return result;
     }
 
     /**
-     *  
-     * @return this
-     * @deprecated Type already has the JavaClass interface
-     */
-    public JavaClass getJavaClass()
-    {
-        return this;
-    }
-
-    /**
+     * @param type the type to match with
+     * @return {@code true} if this type if of type, otherwise {@code false}
      * @since 1.3
      */
     public boolean isA( JavaType type )
@@ -313,9 +300,7 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
         }
     }
 
-    /**
-     * @since 1.6
-     */
+    /** {@inheritDoc} */
     public boolean isPrimitive() {
        return isPrimitive( getValue() );
     }
@@ -334,28 +319,11 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
         
     }
 
-    /**
-     * @since 1.6
-     */
+    /** {@inheritDoc} */
     public boolean isVoid() {
         return "void".equals(getValue());
     }
 
-//    String superSource = "public abstract class Test<T> {\n" + 
-//    "        private T me;\n" + 
-//    "        public Test(T me) {\n" + 
-//    "            this.me = me;\n" + 
-//    "        }\n" + 
-//    "        public T getValue() {\n" + 
-//    "            return me;\n" + 
-//    "        }\n" + 
-//    "    }";
-//String subSource = "public class StringTest extends Test<String> {\n" + 
-//    "        public StringTest(String s) {\n" + 
-//    "            super(s);\n" + 
-//    "        }\n" + 
-//    "    }";
-    
     /**
      *  Consider the following example
      *  
@@ -385,9 +353,10 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
      *   <li>{@code callingClass}  would be ConcreteClass</li>
      *  </ul>
      * 
-     * @param declaringClass
-     * @param callingClass
-     * @return
+     * @param base the base
+     * @param declaringClass the declaring class
+     * @param callingClass the calling class
+     * @return the resolved type
      */
     protected static JavaType resolve( JavaType base, JavaClass declaringClass, JavaClass callingClass )
     {
@@ -421,7 +390,12 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
                     if ( fqn.equals( implement.getFullyQualifiedName() ) )
                     {
                         JavaType actualType = getActualTypeArguments( implement ).get( typeIndex );
-                        JavaType resolvedType = new DefaultJavaType( actualType.getFullyQualifiedName(), actualType.getValue(), getDimensions( base ), implement.getParent() ); 
+                        
+                        TypeResolver typeResolver = TypeResolver.byPackageName( implement.getSource().getPackageName(),
+                                                                                implement.getSource().getJavaClassLibrary(),
+                                                                                implement.getSource().getImports() );
+                        
+                        JavaType resolvedType = new DefaultJavaType( actualType.getFullyQualifiedName(), actualType.getValue(), getDimensions( base ), typeResolver ); 
                         result = resolve( resolvedType , implement, implement );
                         break;
                     }
@@ -442,9 +416,12 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
             {
                 value = value.substring( 0, value.indexOf( '[' ) );
             }
+            
+            TypeResolver typeResolver = TypeResolver.byPackageName(null, declaringClass.getJavaClassLibrary(), null );
+            
             DefaultJavaParameterizedType typeResult =
                 new DefaultJavaParameterizedType( concreteClassName, value, getDimensions( base ),
-                          ((DefaultJavaType)base).getJavaClassParent() );
+                                                  typeResolver );
 
             List<JavaType> actualTypes = new LinkedList<JavaType>();
             for ( JavaType actualArgType : actualTypeArguments )
@@ -462,11 +439,6 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
         return type instanceof JavaClass ? ( (JavaClass) type ).getDimensions() : 0;
     }
     
-    private static JavaClass getDeclaringClass( JavaType type )
-    {
-        return type instanceof JavaClass ? ( (JavaClass) type ).getDeclaringClass() : null;
-    }
-
     private static int getTypeVariableIndex( JavaClass declaringClass, String fqn )
     {
         int typeIndex = -1;
@@ -648,15 +620,9 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
     }
 
     /** {@inheritDoc} */
-    public List<JavaClass> getImplementedInterfaces()
-    {
-        return resolveRealClass().getImplementedInterfaces();
-    }
-    
-    /** {@inheritDoc} */
     public List<JavaClass> getInterfaces()
     {
-        return resolveRealClass().getImplementedInterfaces();
+        return resolveRealClass().getInterfaces();
     }
 
     /** {@inheritDoc} */
@@ -702,24 +668,6 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
     }
 
     /** {@inheritDoc} */
-    public String resolveCanonicalName( String name )
-    {
-        return resolveRealClass().resolveCanonicalName( name );
-    }
-
-    /** {@inheritDoc} */
-    public String resolveFullyQualifiedName( String name )
-    {
-        return resolveRealClass().resolveFullyQualifiedName( name );
-    }
-
-    /** {@inheritDoc} */
-    public String getClassNamePrefix()
-    {
-        return resolveRealClass().getClassNamePrefix();
-    }
-
-    /** {@inheritDoc} */
     public List<JavaInitializer> getInitializers()
     {
         return resolveRealClass().getInitializers();
@@ -879,7 +827,7 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
     /** {@inheritDoc} */
     public ClassLibrary getJavaClassLibrary()
     {
-        return context.getJavaClassLibrary();
+        return resolveRealClass().getJavaClassLibrary();
     }
 
     /** {@inheritDoc} */
@@ -891,7 +839,12 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
     /** {@inheritDoc} */
     public String getCanonicalName()
     {
-        return resolveRealClass().getCanonicalName();
+        StringBuilder result = new StringBuilder( resolveRealClass().getCanonicalName() );
+        for (int i = 0; i < dimensions; i++) 
+        {
+            result.append("[]");
+        }
+        return result.toString();
     }
 
     /** {@inheritDoc} */
@@ -941,38 +894,4 @@ public class DefaultJavaType implements JavaClass, JavaType, Serializable {
     {
         return resolveRealClass().getDeclaringClass();
     } 
-    
-    // deprecated
-    public JavaType asType()    {
-        return resolveRealClass().asType();
-    }
-
-    public List<JavaClass> getClasses()
-    {
-        return resolveRealClass().getClasses();
-    }
-
-    public JavaClass getInnerClassByName( String name )
-    {
-        return resolveRealClass().getInnerClassByName( name );
-    }
-    
-    public List<JavaClass> getInnerClasses()
-    {
-        return resolveRealClass().getInnerClasses();
-    }
-    
-    public JavaClassParent getParent()
-    {
-        return context;
-    }
-
-    public String resolveType( String name )
-    {
-        return resolveRealClass().resolveType( name );
-    }
-    
-    public JavaClassParent getJavaClassParent() {
-        return context;
-    }
 }
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaTypeVariable.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaTypeVariable.java
index e7dcc3f..46a519e 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaTypeVariable.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaTypeVariable.java
@@ -22,12 +22,10 @@ package com.thoughtworks.qdox.model.impl;
 import java.util.Iterator;
 import java.util.List;
 
-import com.thoughtworks.qdox.model.JavaClass;
-import com.thoughtworks.qdox.model.JavaConstructor;
 import com.thoughtworks.qdox.model.JavaGenericDeclaration;
-import com.thoughtworks.qdox.model.JavaMethod;
 import com.thoughtworks.qdox.model.JavaType;
 import com.thoughtworks.qdox.model.JavaTypeVariable;
+import com.thoughtworks.qdox.type.TypeResolver;
 
 /**
  * Equivalent of {@link java.lang.reflect.TypeVariable}
@@ -42,37 +40,12 @@ public class DefaultJavaTypeVariable<D extends JavaGenericDeclaration>
     
     private D genericDeclaration;
 
-    public DefaultJavaTypeVariable( String name, D genericDeclaration )
+    public DefaultJavaTypeVariable( String name, TypeResolver typeResolver )
     {
-        super( name, getContext( genericDeclaration ) );
-        this.genericDeclaration = genericDeclaration;
+        super( name, typeResolver );
     }
-
-    private static JavaClass getContext( JavaGenericDeclaration genericDeclaration )
-    {
-        JavaClass result;
-        if ( genericDeclaration instanceof JavaClass )
-        {
-            result = (JavaClass) genericDeclaration;
-        }
-        else if ( genericDeclaration instanceof JavaMethod )
-        {
-            result = ( (JavaMethod) genericDeclaration ).getDeclaringClass();
-        }
-        else if ( genericDeclaration instanceof JavaConstructor )
-        {
-            result = ( (JavaConstructor) genericDeclaration ).getDeclaringClass();
-        }
-        else
-        {
-            throw new IllegalArgumentException( "Unknown JavaGenericDeclaration implementation" );
-        }
-        return result;
-    }
-
-    /**
-     * @return the bounds
-     */
+    
+    /** {@inheritDoc} */
     public List<JavaType> getBounds()
     {
         return bounds;
@@ -86,6 +59,7 @@ public class DefaultJavaTypeVariable<D extends JavaGenericDeclaration>
         this.bounds = bounds;
     }
     
+    /** {@inheritDoc} */
     public D getGenericDeclaration()
     {
         return genericDeclaration;
@@ -171,14 +145,4 @@ public class DefaultJavaTypeVariable<D extends JavaGenericDeclaration>
     {
         return getValue();
     }
-
-    public String getResolvedValue()
-    {
-        return bounds.get( 0 ).getValue();
-    }
-
-    public String getResolvedFullyQualifiedName()
-    {
-        return bounds.get( 0 ).getFullyQualifiedName();
-    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaWildcardType.java b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaWildcardType.java
index 9123871..1237b49 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaWildcardType.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/DefaultJavaWildcardType.java
@@ -54,6 +54,7 @@ public class DefaultJavaWildcardType extends DefaultJavaType
         this.boundType = boundType;
     }
 
+    @Override
     public String getFullyQualifiedName()
     {
         StringBuilder builder = getPreparedStringBuilder();
@@ -64,6 +65,7 @@ public class DefaultJavaWildcardType extends DefaultJavaType
         return builder.toString();
     }
 
+    @Override
     public String getGenericValue()
     {
         StringBuilder builder = getPreparedStringBuilder();
@@ -74,6 +76,7 @@ public class DefaultJavaWildcardType extends DefaultJavaType
         return builder.toString();
     }
 
+    @Override
     public String getGenericFullyQualifiedName()
     {
         StringBuilder builder = getPreparedStringBuilder();
@@ -84,6 +87,7 @@ public class DefaultJavaWildcardType extends DefaultJavaType
         return builder.toString();
     }
     
+    @Override
     public String getCanonicalName()
     {
         StringBuilder builder = getPreparedStringBuilder();
@@ -93,7 +97,8 @@ public class DefaultJavaWildcardType extends DefaultJavaType
         }
         return builder.toString();
     }
-    
+
+    @Override
     public String getGenericCanonicalName()
     {
         StringBuilder builder = getPreparedStringBuilder();
@@ -104,6 +109,7 @@ public class DefaultJavaWildcardType extends DefaultJavaType
         return builder.toString();
     }
 
+    @Override
     public String getValue()
     {
         StringBuilder builder = getPreparedStringBuilder();
@@ -115,6 +121,7 @@ public class DefaultJavaWildcardType extends DefaultJavaType
 
     }
 
+    @Override
     public String toGenericString()
     {
         StringBuilder builder = getPreparedStringBuilder();
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/JavaClassParent.java b/src/main/java/com/thoughtworks/qdox/model/impl/JavaClassParent.java
deleted file mode 100644
index b719c24..0000000
--- a/src/main/java/com/thoughtworks/qdox/model/impl/JavaClassParent.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.thoughtworks.qdox.model.impl;
-
-import com.thoughtworks.qdox.library.ClassLibrary;
-import com.thoughtworks.qdox.model.JavaClass;
-import com.thoughtworks.qdox.model.JavaSource;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @deprecated this interface will be hidden for the model interfaces
- */
-public interface JavaClassParent {
-
-    /**
-     * Resolve a type-name within the context of this source or class.
-     * @param typeName name of a type
-     * @return the fully-qualified name of the type, or null if it cannot
-     *     be resolved
-     */
-    String resolveType(String typeName);
-    
-    String resolveCanonicalName(String typeName);
-    
-    String resolveFullyQualifiedName(String typeName);
-
-    JavaSource getParentSource();
-
-    JavaClass getNestedClassByName(String name);
-    
-    ClassLibrary getJavaClassLibrary(); 
-    
-}
diff --git a/src/main/java/com/thoughtworks/qdox/model/impl/JavaMethodDelegate.java b/src/main/java/com/thoughtworks/qdox/model/impl/JavaMethodDelegate.java
index 2ac1415..0a1d668 100644
--- a/src/main/java/com/thoughtworks/qdox/model/impl/JavaMethodDelegate.java
+++ b/src/main/java/com/thoughtworks/qdox/model/impl/JavaMethodDelegate.java
@@ -27,9 +27,9 @@ import com.thoughtworks.qdox.model.JavaAnnotation;
 import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaMethod;
 import com.thoughtworks.qdox.model.JavaParameter;
-import com.thoughtworks.qdox.model.JavaSource;
 import com.thoughtworks.qdox.model.JavaType;
 import com.thoughtworks.qdox.model.JavaTypeVariable;
+import com.thoughtworks.qdox.type.TypeResolver;
 
 /**
  * This class can be used to access overridden methods while keeping a reference to the original class.
@@ -55,12 +55,17 @@ public class JavaMethodDelegate implements JavaMethod
         JavaType result = originalMethod.getReturnType( resolve );
         
         if (result != null) {
-            result =  DefaultJavaType.resolve( result, originalMethod.getParentClass(), callingClass );
+            String originalValue = result.getValue();
+            
+            result =  DefaultJavaType.resolve( result, originalMethod.getDeclaringClass(), callingClass );
             
             //According to java-specs, if it could be resolved the upper boundary, so Object, should be returned  
             if ( !resolve && !this.getReturns().getFullyQualifiedName().equals( result.getFullyQualifiedName() ) )
             {
-                result = new DefaultJavaType( "java.lang.Object", 0, callingClass );
+                TypeResolver typeResolver =
+                    TypeResolver.byClassName( callingClass.getBinaryName(), callingClass.getJavaClassLibrary(),
+                                              callingClass.getSource().getImports() );
+                result = new DefaultJavaType( "java.lang.Object", originalValue, 0, typeResolver );
             }
         }
         
@@ -73,11 +78,11 @@ public class JavaMethodDelegate implements JavaMethod
         List<JavaType> result = new LinkedList<JavaType>();
         for ( JavaType type : originalMethod.getParameterTypes( resolve ) )
         {
-            JavaType curType = DefaultJavaType.resolve( type, originalMethod.getParentClass(), callingClass );
+            JavaType curType = DefaultJavaType.resolve( type, originalMethod.getDeclaringClass(), callingClass );
             // According to java-specs, if it could be resolved the upper boundary, so Object, should be returned
             if ( !resolve && !type.getFullyQualifiedName().equals( curType.getFullyQualifiedName() ) )
             {
-                result.add( new DefaultJavaType( "java.lang.Object", 0, callingClass ) );
+                result.add( new DefaultJavaType( "java.lang.Object", 0 ) );
             }
             else
             {
@@ -88,252 +93,278 @@ public class JavaMethodDelegate implements JavaMethod
         return result;
     }
     
+    @Override
     public boolean equals( Object obj )
     {
         return originalMethod.equals( obj );
     }
 
+    /** {@inheritDoc} */
     public List<JavaAnnotation> getAnnotations()
     {
         return originalMethod.getAnnotations();
     }
 
+    /** {@inheritDoc} */
     public String getCallSignature()
     {
         return originalMethod.getCallSignature();
     }
 
+    /** {@inheritDoc} */
     public String getCodeBlock()
     {
         return originalMethod.getCodeBlock();
     }
 
+    /** {@inheritDoc} */
     public String getComment()
     {
         return originalMethod.getComment();
     }
 
+    /** {@inheritDoc} */
     public JavaClass getDeclaringClass() {
     	return originalMethod.getDeclaringClass();
     }
     
+    /** {@inheritDoc} */
     public String getDeclarationSignature( boolean withModifiers )
     {
         return originalMethod.getDeclarationSignature( withModifiers );
     }
 
+    /** {@inheritDoc} */
     public List<JavaClass> getExceptions()
     {
         return originalMethod.getExceptions();
     }
     
+    /** {@inheritDoc} */
     public List<JavaType> getExceptionTypes()
     {
         return originalMethod.getExceptionTypes();
     }
     
+    /** {@inheritDoc} */
     public boolean isDefault()
     {
         return originalMethod.isDefault();
     }
 
+    /** {@inheritDoc} */
     public int getLineNumber()
     {
         return originalMethod.getLineNumber();
     }
 
+    /** {@inheritDoc} */
     public List<String> getModifiers()
     {
         return originalMethod.getModifiers();
     }
 
+    /** {@inheritDoc} */
     public String getName()
     {
         return originalMethod.getName();
     }
 
+    /** {@inheritDoc} */
     public String getNamedParameter( String tagName, String parameterName )
     {
         return originalMethod.getNamedParameter( tagName, parameterName );
     }
 
+    /** {@inheritDoc} */
     public JavaParameter getParameterByName( String name )
     {
         return originalMethod.getParameterByName( name );
     }
 
+    /** {@inheritDoc} */
     public List<JavaParameter> getParameters()
     {
         return originalMethod.getParameters();
     }
     
+    /** {@inheritDoc} */
     public String getPropertyName()
     {
         return originalMethod.getPropertyName();
     }
 
+    /** {@inheritDoc} */
     public JavaType getPropertyType()
     {
         return originalMethod.getPropertyType();
     }
 
+    /** {@inheritDoc} */
     public JavaClass getReturns()
     {
         return originalMethod.getReturns();
     }
 
-    public JavaSource getSource()
-    {
-        return originalMethod.getSource();
-    }
-
+    /** {@inheritDoc} */
     public String getSourceCode()
     {
         return originalMethod.getSourceCode();
     }
 
+    /** {@inheritDoc} */
     public DocletTag getTagByName( String name, boolean inherited )
     {
         return originalMethod.getTagByName( name, inherited );
     }
 
+    /** {@inheritDoc} */
     public DocletTag getTagByName( String name )
     {
         return originalMethod.getTagByName( name );
     }
 
+    /** {@inheritDoc} */
     public List<DocletTag> getTags()
     {
         return originalMethod.getTags();
     }
 
+    /** {@inheritDoc} */
     public List<DocletTag> getTagsByName( String name, boolean inherited )
     {
         return originalMethod.getTagsByName( name, inherited );
     }
 
+    /** {@inheritDoc} */
     public List<DocletTag> getTagsByName( String name )
     {
         return originalMethod.getTagsByName( name );
     }
 
+    /** {@inheritDoc} */
     public List<JavaTypeVariable<JavaMethod>> getTypeParameters()
     {
         return originalMethod.getTypeParameters();
     }
 
+    @Override
     public int hashCode()
     {
         return originalMethod.hashCode();
     }
 
+    /** {@inheritDoc} */
     public boolean isAbstract()
     {
         return originalMethod.isAbstract();
     }
 
+    /** {@inheritDoc} */
     public boolean isFinal()
     {
         return originalMethod.isFinal();
     }
 
+    /** {@inheritDoc} */
     public boolean isNative()
     {
         return originalMethod.isNative();
     }
 
+    /** {@inheritDoc} */
     public boolean isPrivate()
     {
         return originalMethod.isPrivate();
     }
 
+    /** {@inheritDoc} */
     public boolean isPropertyAccessor()
     {
         return originalMethod.isPropertyAccessor();
     }
 
+    /** {@inheritDoc} */
     public boolean isPropertyMutator()
     {
         return originalMethod.isPropertyMutator();
     }
 
+    /** {@inheritDoc} */
     public boolean isProtected()
     {
         return originalMethod.isProtected();
     }
 
+    /** {@inheritDoc} */
     public boolean isPublic()
     {
         return originalMethod.isPublic();
     }
 
+    /** {@inheritDoc} */
     public boolean isStatic()
     {
         return originalMethod.isStatic();
     }
 
+    /** {@inheritDoc} */
     public boolean isStrictfp()
     {
         return originalMethod.isStrictfp();
     }
 
+    /** {@inheritDoc} */
     public boolean isSynchronized()
     {
         return originalMethod.isSynchronized();
     }
 
+    /** {@inheritDoc} */
     public boolean isTransient()
     {
         return originalMethod.isTransient();
     }
 
+    /** {@inheritDoc} */
     public boolean isVarArgs()
     {
         return originalMethod.isVarArgs();
     }
 
+    /** {@inheritDoc} */
     public boolean isVolatile()
     {
         return originalMethod.isVolatile();
     }
 
+    /** {@inheritDoc} */
     public boolean signatureMatches( String name, List<JavaType> parameterTypes, boolean varArg )
     {
         return originalMethod.signatureMatches( name, parameterTypes, varArg );
     }
 
+    /** {@inheritDoc} */
     public boolean signatureMatches( String name, List<JavaType> parameterTypes )
     {
         return originalMethod.signatureMatches( name, parameterTypes );
     }
 
+    /** {@inheritDoc} */
     public String toString()
     {
         return originalMethod.toString();
     }
 
+    /** {@inheritDoc} */
     public JavaType getReturnType()
     {
         return getReturnType( false );
     }
 
+    /** {@inheritDoc} */
     public List<JavaType> getParameterTypes()
     {
         return getParameterTypes( false );
     }
-    
-    // deprecated methods
-    // will be removed with QDox-2.0
-    public JavaClass getParentClass()
-    {
-        return originalMethod.getParentClass();
-    }
-
-    public JavaClass getGenericReturnType()
-    {
-        return originalMethod.getGenericReturnType();
-    }
-
-
-
 }
diff --git a/src/main/java/com/thoughtworks/qdox/model/util/TagParser.java b/src/main/java/com/thoughtworks/qdox/model/util/TagParser.java
index ef2399c..a23c86d 100644
--- a/src/main/java/com/thoughtworks/qdox/model/util/TagParser.java
+++ b/src/main/java/com/thoughtworks/qdox/model/util/TagParser.java
@@ -37,6 +37,9 @@ public final class TagParser {
     
     /**
      * Create a StreamTokenizer suitable for parsing the tag text. 
+     * 
+     * @param tagValue the tag value
+     * @return the tokenizer
      */
     static StreamTokenizer makeTokenizer(String tagValue) {
         StreamTokenizer tokenizer = 
@@ -61,7 +64,10 @@ public final class TagParser {
     }
     
     /**
-     * Extract a Map of named parameters  
+     * Extract a Map of named parameters
+     * 
+     * @param tagValue the tag value
+     * @return a Map with the parameter names and their values
      */
     public static Map<String, String> parseNamedParameters(String tagValue) {
         Map<String, String> paramMap = new LinkedHashMap<String, String>();
@@ -89,6 +95,9 @@ public final class TagParser {
 
     /**
      * Extract an array of positional parameters  
+     * 
+     * @param tagValue the tag value
+     * @return an array with words
      */
     public static String[] parseWords(String tagValue) {
         StreamTokenizer tokenizer = makeTokenizer(tagValue);
@@ -110,6 +119,9 @@ public final class TagParser {
     
     /**
      * Extract an array of parameters as name or name=value representation
+     * 
+     * @param tagValue the tag value
+     * @return the names of the parameters
      * @since 1.11  
      */
     public static List<String> parseParameters(String tagValue) {
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/AddDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/AddDef.java
index 19499f7..7927bd1 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/AddDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/AddDef.java
@@ -26,6 +26,7 @@ public class AddDef extends BinaryOperatorDef {
 		super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/AndDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/AndDef.java
index 88f4f9d..f575981 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/AndDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/AndDef.java
@@ -26,6 +26,7 @@ public class AndDef extends BinaryOperatorDef {
 		super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/AssignmentDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/AssignmentDef.java
index dd82036..d4dfa6e 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/AssignmentDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/AssignmentDef.java
@@ -48,6 +48,7 @@ public class AssignmentDef extends ExpressionDef
         return assignmentExpression;
     }
 
+    /** {@inheritDoc} */
     public <U> U transform( ElemValueTransformer<U> transformer )
     {
         return transformer.transform(this);
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/CastDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/CastDef.java
index 7cfb7a4..daff37e 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/CastDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/CastDef.java
@@ -44,6 +44,7 @@ public class CastDef extends ExpressionDef
         return elemDef;
     }
 
+    /** {@inheritDoc} */
     public <U> U transform( ElemValueTransformer<U> transformer )
     {
         return transformer.transform( this );
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/ConstantDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/ConstantDef.java
index 0852577..3439bb6 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/ConstantDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/ConstantDef.java
@@ -43,6 +43,7 @@ public class ConstantDef extends ExpressionDef {
         return value;
     }
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/CreatorDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/CreatorDef.java
index f0b8eb2..1fdea00 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/CreatorDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/CreatorDef.java
@@ -71,6 +71,7 @@ public class CreatorDef extends ExpressionDef
         this.classBody = classBody;
     }
 
+    /** {@inheritDoc} */
     public <U> U transform( ElemValueTransformer<U> transformer )
     {
         return transformer.transform( this );
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/DivideDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/DivideDef.java
index f1521d1..77f1894 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/DivideDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/DivideDef.java
@@ -26,6 +26,7 @@ public class DivideDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/ElemValueListDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/ElemValueListDef.java
index 06bd353..c10eb37 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/ElemValueListDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/ElemValueListDef.java
@@ -11,6 +11,7 @@ public class ElemValueListDef implements ElemValueDef{
 		this.valueList = annoValueList;
 	}
 
+    /** {@inheritDoc} */
 	public <U> U transform(ElemValueTransformer<U> transformer) {
 		return transformer.transform(this);
 	}
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/ElemValueTransformer.java b/src/main/java/com/thoughtworks/qdox/parser/expression/ElemValueTransformer.java
index d4b0034..3ada9fe 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/ElemValueTransformer.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/ElemValueTransformer.java
@@ -97,5 +97,8 @@ public interface ElemValueTransformer<U>
 
     U transform( MethodInvocationDef methodInvocationDef );
 
+    U transform( MethodReferenceDef methodReferenceDef );
+
     U transform( CreatorDef newCreator );
+
 }
\ No newline at end of file
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/EqualsDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/EqualsDef.java
index 854abf2..5a739bc 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/EqualsDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/EqualsDef.java
@@ -26,6 +26,7 @@ public class EqualsDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/ExclusiveOrDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/ExclusiveOrDef.java
index 71b5ad7..44ed0ac 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/ExclusiveOrDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/ExclusiveOrDef.java
@@ -26,6 +26,7 @@ public class ExclusiveOrDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/FieldRefDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/FieldRefDef.java
index 11c722e..3b885a3 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/FieldRefDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/FieldRefDef.java
@@ -32,6 +32,7 @@ public class FieldRefDef extends ExpressionDef {
         return name;
     }
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/GreaterEqualsDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/GreaterEqualsDef.java
index b2a35a2..457ef97 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/GreaterEqualsDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/GreaterEqualsDef.java
@@ -26,6 +26,7 @@ public class GreaterEqualsDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/GreaterThanDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/GreaterThanDef.java
index f756672..2b98dad 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/GreaterThanDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/GreaterThanDef.java
@@ -26,6 +26,7 @@ public class GreaterThanDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/LessEqualsDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/LessEqualsDef.java
index efa3c5e..c37be88 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/LessEqualsDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/LessEqualsDef.java
@@ -26,6 +26,7 @@ public class LessEqualsDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/LessThanDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/LessThanDef.java
index 154e428..f26d18f 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/LessThanDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/LessThanDef.java
@@ -26,6 +26,7 @@ public class LessThanDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalAndDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalAndDef.java
index 250f259..1537d21 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalAndDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalAndDef.java
@@ -26,6 +26,7 @@ public class LogicalAndDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalNotDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalNotDef.java
index ff1d5ff..0064119 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalNotDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalNotDef.java
@@ -26,6 +26,7 @@ public class LogicalNotDef extends UnaryOperatorDef {
     	super(value);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalOrDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalOrDef.java
index 7ef0330..01e783a 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalOrDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/LogicalOrDef.java
@@ -26,6 +26,7 @@ public class LogicalOrDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/MethodInvocationDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/MethodInvocationDef.java
index e73047a..94b0e98 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/MethodInvocationDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/MethodInvocationDef.java
@@ -43,6 +43,7 @@ public class MethodInvocationDef extends ExpressionDef
         return arguments;
     }
 
+    /** {@inheritDoc} */
     public <U> U transform( ElemValueTransformer<U> transformer )
     {
         return transformer.transform( this );
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/MethodReferenceDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/MethodReferenceDef.java
new file mode 100644
index 0000000..54e153e
--- /dev/null
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/MethodReferenceDef.java
@@ -0,0 +1,10 @@
+package com.thoughtworks.qdox.parser.expression;
+
+public class MethodReferenceDef extends ExpressionDef
+{
+    /** {@inheritDoc} */
+    public <U> U transform( ElemValueTransformer<U> transformer )
+    {
+        return transformer.transform( this );
+    }
+}
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/MinusSignDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/MinusSignDef.java
index ae3e95b..16e2b1a 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/MinusSignDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/MinusSignDef.java
@@ -26,6 +26,7 @@ public class MinusSignDef extends UnaryOperatorDef {
 		super(value);
 	}
 
+    /** {@inheritDoc} */
 	public <U> U transform(ElemValueTransformer<U> transformer) {
 		return transformer.transform(this);
 	}
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/MultiplyDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/MultiplyDef.java
index f3cecde..5367124 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/MultiplyDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/MultiplyDef.java
@@ -26,6 +26,7 @@ public class MultiplyDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/NotDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/NotDef.java
index 9cc9a4e..ac99657 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/NotDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/NotDef.java
@@ -26,6 +26,7 @@ public class NotDef extends UnaryOperatorDef {
     	super(value);
 	}
     
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/NotEqualsDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/NotEqualsDef.java
index 35cbc11..a022e14 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/NotEqualsDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/NotEqualsDef.java
@@ -26,6 +26,7 @@ public class NotEqualsDef extends BinaryOperatorDef {
 		super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/OrDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/OrDef.java
index 0021322..6cc8006 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/OrDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/OrDef.java
@@ -26,6 +26,7 @@ public class OrDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/ParenExpressionDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/ParenExpressionDef.java
index 161ff30..c0d7992 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/ParenExpressionDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/ParenExpressionDef.java
@@ -27,6 +27,7 @@ public class ParenExpressionDef extends ExpressionDef {
     	this.elemValueDef = value;
 	}
     
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/PlusSignDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/PlusSignDef.java
index 8579565..cbafffb 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/PlusSignDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/PlusSignDef.java
@@ -26,6 +26,7 @@ public class PlusSignDef extends UnaryOperatorDef {
 		super(value);
 	}
 
+    /** {@inheritDoc} */
 	public <U> U transform(ElemValueTransformer<U> transformer) {
 		return transformer.transform(this);
 	}
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/PostDecrementDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/PostDecrementDef.java
index e8bda02..66a84cd 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/PostDecrementDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/PostDecrementDef.java
@@ -26,6 +26,7 @@ public class PostDecrementDef extends UnaryOperatorDef
         super( elemValueDef );
     }
 
+    /** {@inheritDoc} */
     public <U> U transform( ElemValueTransformer<U> transformer )
     {
         return transformer.transform( this );
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/PostIncrementDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/PostIncrementDef.java
index 3599d02..267da63 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/PostIncrementDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/PostIncrementDef.java
@@ -26,6 +26,7 @@ public class PostIncrementDef extends UnaryOperatorDef
         super( elemValueDef );
     }
 
+    /** {@inheritDoc} */
     public <U> U transform( ElemValueTransformer<U> transformer )
     {
         return transformer.transform( this );
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/PreDecrementDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/PreDecrementDef.java
index 2d3ca66..fdaa20d 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/PreDecrementDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/PreDecrementDef.java
@@ -26,6 +26,7 @@ public class PreDecrementDef extends UnaryOperatorDef
         super( elemValueDef );
     }
 
+    /** {@inheritDoc} */
     public <U> U transform( ElemValueTransformer<U> transformer )
     {
         return transformer.transform( this );
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/PreIncrementDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/PreIncrementDef.java
index e109509..14d6fc7 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/PreIncrementDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/PreIncrementDef.java
@@ -26,6 +26,7 @@ public class PreIncrementDef extends UnaryOperatorDef
         super( elemValueDef );
     }
 
+    /** {@inheritDoc} */
     public <U> U transform( ElemValueTransformer<U> transformer )
     {
         return transformer.transform( this );
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/QueryDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/QueryDef.java
index 1a9e4ce..ca772e3 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/QueryDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/QueryDef.java
@@ -33,6 +33,7 @@ public class QueryDef  extends ExpressionDef {
     	this.falseExpr = falseExpr;
 	}
     
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/RemainderDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/RemainderDef.java
index 431d3e3..1ad8aec 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/RemainderDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/RemainderDef.java
@@ -26,6 +26,7 @@ public class RemainderDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/ShiftLeftDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/ShiftLeftDef.java
index 03d8f2f..9122866 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/ShiftLeftDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/ShiftLeftDef.java
@@ -26,6 +26,7 @@ public class ShiftLeftDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/ShiftRightDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/ShiftRightDef.java
index f83ab72..c20426a 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/ShiftRightDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/ShiftRightDef.java
@@ -26,6 +26,7 @@ public class ShiftRightDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/SubtractDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/SubtractDef.java
index 35b5800..936dd78 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/SubtractDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/SubtractDef.java
@@ -26,6 +26,7 @@ public class SubtractDef extends BinaryOperatorDef {
     	super(lhs, rhs);
 	}
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/TypeRefDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/TypeRefDef.java
index e3e4877..28f04a4 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/TypeRefDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/TypeRefDef.java
@@ -29,6 +29,7 @@ public class TypeRefDef  extends ExpressionDef {
 		this.typeDef = typeDef;
 	}
     
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/expression/UnsignedShiftRightDef.java b/src/main/java/com/thoughtworks/qdox/parser/expression/UnsignedShiftRightDef.java
index c9a3a86..76c7ec6 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/expression/UnsignedShiftRightDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/expression/UnsignedShiftRightDef.java
@@ -26,6 +26,7 @@ public class UnsignedShiftRightDef extends BinaryOperatorDef {
     	super(lhs, rhs);
     }
 
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/impl/BinaryClassParser.java b/src/main/java/com/thoughtworks/qdox/parser/impl/BinaryClassParser.java
index f78b31e..0ee4d39 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/impl/BinaryClassParser.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/impl/BinaryClassParser.java
@@ -50,11 +50,10 @@ public class BinaryClassParser
     {
         try
         {
-            String name = declaringClazz.getName();
-
-            // Set the package name and class name
-            String packageName = getPackageName( name );
-            binaryBuilder.addPackage( new PackageDef( packageName ) );
+            if(declaringClazz.getPackage() != null)
+            {
+                binaryBuilder.addPackage( new PackageDef( declaringClazz.getPackage().getName() ) );
+            }
 
             addClass( declaringClazz );
 
@@ -69,12 +68,20 @@ public class BinaryClassParser
     private void addClass( Class<?> clazz )
     {
         ClassDef classDef = new ClassDef( clazz.getSimpleName() );
-
+        
         // Set the extended class and interfaces.
         Class<?>[] interfaces = clazz.getInterfaces();
-        if ( clazz.isInterface() )
+        
+        if ( clazz.isEnum() )
+        {
+            classDef.setType( ClassDef.ENUM );
+        }
+        else if ( clazz.isAnnotation() )
+        {
+            classDef.setType( ClassDef.ANNOTATION_TYPE );
+        }
+        else if ( clazz.isInterface() )
         {
-            // It's an interface
             classDef.setType( ClassDef.INTERFACE );
             for ( int i = 0; i < interfaces.length; i++ )
             {
@@ -84,7 +91,6 @@ public class BinaryClassParser
         }
         else
         {
-            // It's a class
             for ( int i = 0; i < interfaces.length; i++ )
             {
                 Class<?> anInterface = interfaces[i];
@@ -134,7 +140,6 @@ public class BinaryClassParser
         {
             addClass( classes[i] );
         }
-        
 
         binaryBuilder.endClass();
     }
@@ -222,10 +227,4 @@ public class BinaryClassParser
     {
         return new TypeDef( getTypeName( c ) );
     }
-
-    private String getPackageName( String fullClassName )
-    {
-        int lastDot = fullClassName.lastIndexOf( '.' );
-        return lastDot == -1 ? "" : fullClassName.substring( 0, lastDot );
-    }
 }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/structs/AnnoDef.java b/src/main/java/com/thoughtworks/qdox/parser/structs/AnnoDef.java
index 6e9593f..6206a21 100644
--- a/src/main/java/com/thoughtworks/qdox/parser/structs/AnnoDef.java
+++ b/src/main/java/com/thoughtworks/qdox/parser/structs/AnnoDef.java
@@ -39,6 +39,7 @@ public class AnnoDef extends LocatedDef implements ElemValueDef
     	return this;
     }
     
+    /** {@inheritDoc} */
     public <U> U transform(ElemValueTransformer<U> transformer) {
     	return transformer.transform(this);
     }
diff --git a/src/main/java/com/thoughtworks/qdox/parser/structs/ModuleDef.java b/src/main/java/com/thoughtworks/qdox/parser/structs/ModuleDef.java
new file mode 100644
index 0000000..838b463
--- /dev/null
+++ b/src/main/java/com/thoughtworks/qdox/parser/structs/ModuleDef.java
@@ -0,0 +1,149 @@
+package com.thoughtworks.qdox.parser.structs;
+
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+public class ModuleDef extends LocatedDef
+{
+    private boolean open;
+    
+    private String name;
+
+    public ModuleDef( String name )
+    {
+        super();
+        this.name = name;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setOpen( boolean open )
+    {
+        this.open = open;
+    }
+    
+    public boolean isOpen()
+    {
+        return open;
+    }
+    
+    public static class ExportsDef extends LocatedDef
+    {
+        private String source;
+        
+        private Set<String> targets = new LinkedHashSet<String>();
+
+        public ExportsDef( String source )
+        {
+            this.source = source;
+        }
+        
+        public ExportsDef( String source, Set<String> modifiers )
+        {
+            this.source = source;
+        }
+
+        public String getSource()
+        {
+            return source;
+        }
+
+        public Set<String> getTargets()
+        {
+            return targets;
+        }
+    }
+    
+    public static class OpensDef extends LocatedDef
+    {
+        private String source;
+        
+        private Set<String> targets = new LinkedHashSet<String>();
+
+        public OpensDef( String source )
+        {
+            this.source = source;
+        }
+        
+        public OpensDef( String source, Set<String> modifiers )
+        {
+            this.source = source;
+        }
+
+        public String getSource()
+        {
+            return source;
+        }
+
+        public Set<String> getTargets()
+        {
+            return targets;
+        }
+    }
+    
+    public static class ProvidesDef extends LocatedDef
+    {
+        private TypeDef service;
+        
+        private List<TypeDef> implementations = new LinkedList<TypeDef>();
+
+        public ProvidesDef( TypeDef service )
+        {
+            this.service = service;
+        }
+
+        public TypeDef getService()
+        {
+            return service;
+        }
+
+        public List<TypeDef> getImplementations()
+        {
+            return implementations;
+        }
+    }
+    
+    public static class RequiresDef extends LocatedDef
+    {
+        private String name;
+        
+        private Set<String> modifiers;
+        
+        public RequiresDef( String name, Set<String> modifiers )
+        {
+            super();
+            this.name = name;
+            this.modifiers = modifiers;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+        
+        public Set<String> getModifiers()
+        {
+            return modifiers;
+        }
+    }
+    
+    public static class UsesDef extends LocatedDef
+    {
+        private TypeDef service;
+
+        public UsesDef( TypeDef service )
+        {
+            this.service = service;
+        }
+
+        public TypeDef getService()
+        {
+            return service;
+        } 
+    }
+}
diff --git a/src/main/java/com/thoughtworks/qdox/type/TypeResolver.java b/src/main/java/com/thoughtworks/qdox/type/TypeResolver.java
new file mode 100644
index 0000000..28a36b0
--- /dev/null
+++ b/src/main/java/com/thoughtworks/qdox/type/TypeResolver.java
@@ -0,0 +1,287 @@
+package com.thoughtworks.qdox.type;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.thoughtworks.qdox.library.ClassLibrary;
+import com.thoughtworks.qdox.model.JavaClass;
+
+/**
+ * A per JavaClass resolver of types
+ *  
+ * @author Robert Scholte
+ * @since 2.0
+ */
+public class TypeResolver
+{
+    private static final Set<String> PRIMITIVE_TYPES = new HashSet<String>();
+
+    private final Map<String, String> resolvedTypeCache = new HashMap<String, String>();
+
+    private final String pckg;
+    
+    private final String declaringClass;
+
+    private final ClassLibrary classLibrary;
+    
+    private final Collection<String> imports;
+    
+    static {
+        PRIMITIVE_TYPES.add("boolean");
+        PRIMITIVE_TYPES.add("byte");
+        PRIMITIVE_TYPES.add("char");
+        PRIMITIVE_TYPES.add("double");
+        PRIMITIVE_TYPES.add("float");
+        PRIMITIVE_TYPES.add("int");
+        PRIMITIVE_TYPES.add("long");
+        PRIMITIVE_TYPES.add("short");
+        PRIMITIVE_TYPES.add("void");
+    }
+
+    private TypeResolver( String pckg, String declaringClass, ClassLibrary classLibrary, Collection<String> imports )
+    {
+        this.pckg = pckg;
+        this.declaringClass = declaringClass;
+        this.classLibrary = classLibrary;
+        this.imports = imports != null ? imports : Collections.<String>emptyList();
+    }
+    
+    /**
+     * Type resolver in case there's no declaring class, e.g. using extends, implements and annotations on a toplevel class
+     * 
+     * @param binaryName the binary name of the package
+     * @param classLibrary the class library
+     * @param imports the imports, can be {@code null}
+     * @return the typeResolver
+     */
+    public static TypeResolver byPackageName( String binaryName, ClassLibrary classLibrary, Collection<String> imports )
+    {
+        return new TypeResolver( binaryName, null, classLibrary, imports );
+    }
+    
+    /**
+     * 
+     * @param binaryName the class in which context a type is used.
+     * @param classLibrary the class library
+     * @param imports the imports, can be {@code null}
+     * @return the typeResolver
+     */
+    public static TypeResolver byClassName( String binaryName, ClassLibrary classLibrary, Collection<String> imports )
+    {
+        int dotIndex = binaryName.lastIndexOf( '.' );
+        String pckg = dotIndex > 0 ? binaryName.substring( 0, dotIndex ) : null;   
+        return new TypeResolver( pckg, binaryName, classLibrary, imports );
+    }
+    
+    public JavaClass resolveJavaClass( String typeName )
+    {
+        return classLibrary.getJavaClass( resolveType( typeName ) );
+    }
+
+    public JavaClass getJavaClass( String binaryName )
+    {
+        return classLibrary.getJavaClass( binaryName );
+    }
+
+    public String resolveType( String typeName )
+    {
+        String result = resolvedTypeCache.get( typeName );
+        if ( result == null )
+        {
+            if ( declaringClass != null )
+            {
+                
+                int dollarIndex = declaringClass.indexOf( '$' );
+                
+                while( result == null && dollarIndex > 0 )
+                {
+                    String subType = declaringClass.substring( 0, dollarIndex + 1 ) + typeName;
+                    
+                    result = resolveFromLibrary( subType );
+                    
+                    dollarIndex = declaringClass.indexOf( '$', dollarIndex + 1 );
+                }
+
+                if (result == null)
+                {
+                    String nestedBinaryName = declaringClass + '$' + typeName.replace( '.', '$' );
+
+                    result = resolveFromLibrary( nestedBinaryName );;
+                }
+            }
+
+            if ( result == null )
+            {
+                result = resolveTypeInternal( typeName );
+            }
+
+            if ( result != null )
+            {
+                resolvedTypeCache.put( typeName, result );
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Resolves a type name
+     * <p>
+     * Follows the <a href="http://java.sun.com/docs/books/jls/third_edition/html/packages.html#7.5.1">
+     * Java Language Specification, Version 3.0</a>.
+     * <p>
+     * Current resolution order is:
+     * <ol>
+     * <li>Single-Type-Import Declaration</li>
+     * <li>Type-Import-on-Demand Declaration</li>
+     * <li>Automatic Imports</li>
+     * </ol>
+     * 
+     * @param typeName the name to resolve
+     * @return the resolved type name, otherwise <code>null</code>
+     */
+    private String resolveTypeInternal( String typeName )
+    {
+        String resolvedName = null;
+
+        lookup:
+        {
+            // primitive types
+            if ( PRIMITIVE_TYPES.contains( typeName ) )
+            {
+                resolvedName = typeName;
+                break lookup;
+            }
+
+            String outerName = typeName;
+            String nestedName = typeName.replace( '.', '$' );
+            int dotpos = typeName.indexOf( '.' );
+
+            if ( dotpos >= 0 )
+            {
+                outerName = typeName.substring( 0, dotpos );
+            }
+
+            // Check single-type-import with fully qualified name
+            resolvedName = resolveImportedType( typeName, nestedName, true );
+
+            if ( resolvedName != null )
+            {
+                break lookup;
+            }
+
+            // Check single-type-import with outer name
+            resolvedName = resolveImportedType( outerName, nestedName, false );
+
+            if ( resolvedName != null )
+            {
+                break lookup;
+            }
+
+            // check for class in the same package
+            if ( pckg != null )
+            {
+                resolvedName = resolveFullyQualifiedType( pckg + '.' + typeName );
+
+                if ( resolvedName != null )
+                {
+                    break lookup;
+                }
+            }
+
+            // check for a class globally
+            resolvedName = resolveFullyQualifiedType( typeName );
+
+            if ( resolvedName != null )
+            {
+                break lookup;
+            }
+
+            // check for a class in the same package
+            if ( pckg != null )
+            {
+                resolvedName = resolveFromLibrary( pckg + "$" + nestedName );
+                if ( resolvedName != null )
+                {
+                    break lookup;
+                }
+            }
+
+            // try java.lang.*
+            resolvedName = resolveFromLibrary( "java.lang." + nestedName );
+            if ( resolvedName != null )
+            {
+                break lookup;
+            }
+
+            // Check type-import-on-demand
+            resolvedName = resolveImportedType( "*", nestedName, false );
+
+            if ( resolvedName != null )
+            {
+                break lookup;
+            }
+        }
+
+        return resolvedName;
+    }
+
+    private String resolveImportedType( String importSpec, String typeName, boolean fullMatch )
+    {
+        String resolvedName = null;
+        String dotSuffix = "." + importSpec;
+
+        for ( String imprt : imports )
+        {
+            // static imports can refer to inner classes
+            if ( imprt.startsWith( "static " ) )
+            {
+                imprt = imprt.substring( 7 );
+            }
+            if ( imprt.equals( importSpec ) || ( !fullMatch && imprt.endsWith( dotSuffix ) ) )
+            {
+                String candidateName = imprt.equals(importSpec) ? imprt
+                                : imprt.substring(0, imprt.length() - importSpec.length()) + typeName;
+
+                resolvedName = resolveFullyQualifiedType( candidateName );
+                if ( resolvedName == null && !"*".equals( importSpec ) )
+                {
+                    resolvedName = candidateName;
+                }
+                if ( resolvedName != null )
+                {
+                    break;
+                }
+            }
+        }
+
+        return resolvedName;
+    }
+
+    private String resolveFromLibrary(String typeName) {
+        return classLibrary.hasClassReference( typeName ) ? typeName : null;
+    }
+
+    private String resolveFullyQualifiedType(String typeName) {
+        int indexOfLastDot = typeName.lastIndexOf('.');
+        
+        if (indexOfLastDot >= 0) {
+            String root = typeName.substring(0,indexOfLastDot);
+            String leaf = typeName.substring(indexOfLastDot+1);
+            String resolvedTypeName = resolveFullyQualifiedType(root + '$' + leaf);
+            
+            if(resolvedTypeName != null) {
+                return resolvedTypeName;
+            }
+        }
+
+        if( classLibrary.hasClassReference( typeName )) 
+        {
+            return typeName;
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/com/thoughtworks/qdox/writer/ModelWriter.java b/src/main/java/com/thoughtworks/qdox/writer/ModelWriter.java
index 7480264..821b735 100644
--- a/src/main/java/com/thoughtworks/qdox/writer/ModelWriter.java
+++ b/src/main/java/com/thoughtworks/qdox/writer/ModelWriter.java
@@ -25,6 +25,7 @@ import com.thoughtworks.qdox.model.JavaConstructor;
 import com.thoughtworks.qdox.model.JavaField;
 import com.thoughtworks.qdox.model.JavaInitializer;
 import com.thoughtworks.qdox.model.JavaMethod;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor;
 import com.thoughtworks.qdox.model.JavaPackage;
 import com.thoughtworks.qdox.model.JavaParameter;
 import com.thoughtworks.qdox.model.JavaSource;
@@ -180,5 +181,68 @@ public interface ModelWriter
      * @return itself
      */
     ModelWriter writeInitializer( JavaInitializer init );
+    
+    /**
+     * Write the module descriptor
+     * 
+     * A standard module descriptor writer should write:
+     * <ul>
+     *   <li>the javadoc</li>
+     *   <li>the annotations</li>
+     *   <li>the module signature, containing:
+     *     <ul>
+     *       <li>the requires statements</li>
+     *       <li>the exports statements</li>
+     *       <li>the opens statements</li>
+     *       <li>the uses statements</li>
+     *       <li>the provides statements</li>
+     *     </ul>
+     *   </li>
+     * </ul>
+     * 
+     * @param descriptor the module declaration
+     * @return itself
+     */
+    ModelWriter writeModuleDescriptor( JavaModuleDescriptor descriptor );
+    
+    /**
+     * Write the module descriptors exports
+     * 
+     * @param exports the exports module statement
+     * @return itself
+     */
+    ModelWriter writeModuleExports( JavaModuleDescriptor.JavaExports exports );
+
+    /**
+     * Write the module descriptors opens
+     * 
+     * @param opens the opens module statement
+     * @return itself
+     */
+    ModelWriter writeModuleOpens( JavaModuleDescriptor.JavaOpens opens );
+    
+    /**
+     * Write the module descriptors provides
+     * 
+     * @param provides the provides module statement
+     * @return itself
+     */
+    ModelWriter writeModuleProvides( JavaModuleDescriptor.JavaProvides provides );
+    
+    /**
+     * Write the module descriptors requires
+     * 
+     * @param requires the requires module statement
+     * @return itself
+     */
+    ModelWriter writeModuleRequires( JavaModuleDescriptor.JavaRequires requires );
+
+    /**
+     * Write the module descriptors uses
+     * 
+     * @param uses the uses module statement
+     * @return itself
+     */
+    ModelWriter writeModuleUses( JavaModuleDescriptor.JavaUses uses );
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/thoughtworks/qdox/writer/impl/DefaultModelWriter.java b/src/main/java/com/thoughtworks/qdox/writer/impl/DefaultModelWriter.java
index 0fbc1f9..ca4d86e 100644
--- a/src/main/java/com/thoughtworks/qdox/writer/impl/DefaultModelWriter.java
+++ b/src/main/java/com/thoughtworks/qdox/writer/impl/DefaultModelWriter.java
@@ -1,5 +1,7 @@
 package com.thoughtworks.qdox.writer.impl;
 
+import java.util.Collection;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -32,6 +34,13 @@ import com.thoughtworks.qdox.model.JavaConstructor;
 import com.thoughtworks.qdox.model.JavaField;
 import com.thoughtworks.qdox.model.JavaInitializer;
 import com.thoughtworks.qdox.model.JavaMethod;
+import com.thoughtworks.qdox.model.JavaModule;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaExports;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaOpens;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaProvides;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaRequires;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaUses;
 import com.thoughtworks.qdox.model.JavaPackage;
 import com.thoughtworks.qdox.model.JavaParameter;
 import com.thoughtworks.qdox.model.JavaSource;
@@ -344,7 +353,7 @@ public class DefaultModelWriter
         return this;
     }
 
-    private void writeNonAccessibilityModifiers( List<String> modifiers )
+    private void writeNonAccessibilityModifiers( Collection<String> modifiers )
     {
         for ( String modifier : modifiers )
         {
@@ -356,7 +365,7 @@ public class DefaultModelWriter
         }
     }
 
-    private void writeAccessibilityModifier( List<String> modifiers )
+    private void writeAccessibilityModifier( Collection<String> modifiers )
     {
         for ( String modifier : modifiers )
         {
@@ -468,6 +477,144 @@ public class DefaultModelWriter
         }
     }
 
+    /** {@inheritDoc} */
+    public ModelWriter writeModuleDescriptor( JavaModuleDescriptor descriptor )
+    {
+        if( descriptor.isOpen() ) {
+            buffer.write( "open " );
+        }
+        buffer.write( "module " + descriptor.getName() +  " {");
+        buffer.newline();
+        buffer.indent();
+
+        for ( JavaRequires requires : descriptor.getRequires() )
+        {
+            buffer.newline();
+            writeModuleRequires( requires );
+        }
+
+        for ( JavaExports exports : descriptor.getExports() )
+        {
+            buffer.newline();
+            writeModuleExports( exports );
+        }
+        
+        for ( JavaOpens opens : descriptor.getOpens() )
+        {
+            buffer.newline();
+            writeModuleOpens( opens );
+        }
+
+        for ( JavaProvides provides : descriptor.getProvides() )
+        {
+            buffer.newline();
+            writeModuleProvides( provides );
+        }
+
+        for ( JavaUses uses : descriptor.getUses() )
+        {
+            buffer.newline();
+            writeModuleUses( uses );
+        }
+
+        buffer.newline();
+        buffer.deindent();
+        buffer.write( '}' );
+        buffer.newline();
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    public ModelWriter writeModuleExports( JavaExports exports )
+    {
+        buffer.write( "exports " );
+        buffer.write( exports.getSource().getName() );
+        if( !exports.getTargets().isEmpty() )
+        {
+            buffer.write( " to " );
+            Iterator<JavaModule> targets = exports.getTargets().iterator();
+            while( targets.hasNext() )
+            {
+                JavaModule target = targets.next();
+                buffer.write( target.getName() );
+                if( targets.hasNext() )
+                {
+                    buffer.write( ", " );
+                }
+            }
+        }
+        buffer.write( ';' );
+        buffer.newline();
+        return this;
+    }
+    
+    /** {@inheritDoc} */
+    public ModelWriter writeModuleOpens( JavaOpens opens )
+    {
+        buffer.write( "opens " );
+        buffer.write( opens.getSource().getName() );
+        if( !opens.getTargets().isEmpty() )
+        {
+            buffer.write( " to " );
+            Iterator<JavaModule> targets = opens.getTargets().iterator();
+            while( targets.hasNext() )
+            {
+                JavaModule target = targets.next();
+                buffer.write( target.getName() );
+                if( targets.hasNext() )
+                {
+                    buffer.write( ", " );
+                }
+            }
+        }
+        buffer.write( ';' );
+        buffer.newline();
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    public ModelWriter writeModuleProvides( JavaProvides provides )
+    {
+        buffer.write( "provides " );
+        buffer.write( provides.getService().getName() );
+        buffer.write( " with " );
+        Iterator<JavaClass> providers = provides.getProviders().iterator();
+        while( providers.hasNext() )
+        {
+            JavaClass provider = providers.next();
+            buffer.write( provider.getName() );
+            if( providers.hasNext() )
+            {
+                buffer.write( ", " );
+            }
+        }
+        buffer.write( ';' );
+        buffer.newline();
+        return null;
+    }
+    
+    /** {@inheritDoc} */
+    public ModelWriter writeModuleRequires( JavaRequires requires )
+    {
+        buffer.write( "requires " );
+        writeAccessibilityModifier( requires.getModifiers() );
+        writeNonAccessibilityModifiers( requires.getModifiers() );
+        buffer.write( requires.getModule().getName() );
+        buffer.write( ';' );
+        buffer.newline();
+        return this;
+    }
+    
+    /** {@inheritDoc} */
+    public ModelWriter writeModuleUses( JavaUses uses )
+    {
+        buffer.write( "uses " );
+        buffer.write( uses.getService().getName() );
+        buffer.write( ';' );
+        buffer.newline();
+        return this;
+    }
+
     @Override
     public String toString()
     {
diff --git a/src/main/java/com/thoughtworks/qdox/writer/impl/IndentBuffer.java b/src/main/java/com/thoughtworks/qdox/writer/impl/IndentBuffer.java
index 71d6573..191c97f 100644
--- a/src/main/java/com/thoughtworks/qdox/writer/impl/IndentBuffer.java
+++ b/src/main/java/com/thoughtworks/qdox/writer/impl/IndentBuffer.java
@@ -68,6 +68,7 @@ public class IndentBuffer
         depth--;
     }
 
+    @Override
     public String toString()
     {
         return buffer.toString();
diff --git a/src/test/java/X.java b/src/test/java/X.java
new file mode 100644
index 0000000..bc9dd9d
--- /dev/null
+++ b/src/test/java/X.java
@@ -0,0 +1,17 @@
+public class X
+{
+    enum EnumWithConstructors
+    {
+        c( "hello" ), d();
+
+        int someField;
+
+        EnumWithConstructors()
+        {
+        }
+
+        EnumWithConstructors( String x )
+        {
+        }
+    }
+}
diff --git a/src/test/java/com/thoughtworks/qdox/ClassResolutionTest.java b/src/test/java/com/thoughtworks/qdox/ClassResolutionTest.java
index 606c624..d9747b5 100644
--- a/src/test/java/com/thoughtworks/qdox/ClassResolutionTest.java
+++ b/src/test/java/com/thoughtworks/qdox/ClassResolutionTest.java
@@ -37,6 +37,8 @@ public class ClassResolutionTest
 
         // verify
         assertEquals( "Should include fully qualified name", "package1.Class1$NestedClass",
+                      type.getBinaryName() );
+        assertEquals( "Should include fully qualified name", "package1.Class1.NestedClass",
                       type.getFullyQualifiedName() );
     }
 
@@ -82,8 +84,11 @@ public class ClassResolutionTest
         builder.addSource( new StringReader( source ) );
         JavaMethod method = builder.getClassByName( "some.pack.Test" ).getMethods().get( 0 );
         JavaParameter parameter = method.getParameters().get( 0 );
-        assertEquals( "some.pack.Test$Inner$Inner2", parameter.getJavaClass().getFullyQualifiedName() );
-        assertEquals( "some.pack.Test$Inner$Inner2", parameter.getType().getFullyQualifiedName() );
-        assertEquals( "some.pack.Test$Inner$Inner2", parameter.getFullyQualifiedName() );
+        assertEquals( "some.pack.Test$Inner$Inner2", parameter.getJavaClass().getBinaryName() );
+        assertEquals( "some.pack.Test$Inner$Inner2", parameter.getType().getBinaryName() );
+        assertEquals( "some.pack.Test$Inner$Inner2", parameter.getBinaryName() );
+        assertEquals( "some.pack.Test.Inner.Inner2", parameter.getJavaClass().getFullyQualifiedName() );
+        assertEquals( "some.pack.Test.Inner.Inner2", parameter.getType().getFullyQualifiedName() );
+        assertEquals( "some.pack.Test.Inner.Inner2", parameter.getFullyQualifiedName() );
     }
 }
diff --git a/src/test/java/com/thoughtworks/qdox/EnumsModelTest.java b/src/test/java/com/thoughtworks/qdox/EnumsModelTest.java
index bebc148..dbf0dd0 100644
--- a/src/test/java/com/thoughtworks/qdox/EnumsModelTest.java
+++ b/src/test/java/com/thoughtworks/qdox/EnumsModelTest.java
@@ -1,13 +1,16 @@
 package com.thoughtworks.qdox;
 
+import java.io.File;
 import java.io.StringReader;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.List;
 
-import junit.framework.TestCase;
-
 import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaField;
 
+import junit.framework.TestCase;
+
 
 public class EnumsModelTest extends TestCase {
 
@@ -72,7 +75,8 @@ public class EnumsModelTest extends TestCase {
         assertNotNull( enum2d.getComment() );
         assertEquals( 0, enum2d.getModifiers().size() );
         assertEquals( 0, enum2d.getAnnotations().size() );
-        assertEquals( "X$Enum2", enum2d.getType().getFullyQualifiedName() );
+        assertEquals( "X$Enum2", enum2d.getType().getBinaryName() );
+        assertEquals( "X.Enum2", enum2d.getType().getFullyQualifiedName() );
         assertEquals( "d", enum2d.getName() );
 
         //---
@@ -119,7 +123,7 @@ public class EnumsModelTest extends TestCase {
         //---
     }
     
-    public void testAddEnumWithFieldAndConstructorsToModel() {
+    public void testAddEnumWithFieldAndConstructorsToModelSource() {
 
         String source = ""
                 + "class X {\n"
@@ -152,7 +156,8 @@ public class EnumsModelTest extends TestCase {
         assertNull( enum1c.getComment() );
         assertEquals( 0, enum1c.getModifiers().size() );
         assertEquals( 0, enum1c.getAnnotations().size() );
-        assertEquals( "X$EnumWithConstructors", enum1c.getType().getFullyQualifiedName() );
+        assertEquals( "X$EnumWithConstructors", enum1c.getType().getBinaryName() );
+        assertEquals( "X.EnumWithConstructors", enum1c.getType().getFullyQualifiedName() );
         assertEquals( "c", enum1c.getName() );
 
         //---
@@ -160,7 +165,39 @@ public class EnumsModelTest extends TestCase {
         JavaField enum1d = fields.get(1);
         assertNull( enum1d.getComment() );
         assertEquals( 0, enum1d.getModifiers().size() );
-        assertEquals( "X$EnumWithConstructors", enum1d.getType().getFullyQualifiedName() );
+        assertEquals( "X$EnumWithConstructors", enum1d.getType().getBinaryName() );
+        assertEquals( "X.EnumWithConstructors", enum1d.getType().getFullyQualifiedName() );
+        assertEquals( "d", enum1d.getName() );
+
+        //---
+    }
+    
+    public void testAddEnumWithFieldAndConstructorsToModelBinary() throws Exception
+    {
+        JavaProjectBuilder javaDocBuilder = new JavaProjectBuilder();
+        javaDocBuilder.addClassLoader( new URLClassLoader( new URL[] { new File("target/test-classes/").toURI().toURL() } )  );
+        
+        JavaClass cls = javaDocBuilder.getClassByName("X$EnumWithConstructors");
+        assertTrue(cls.isEnum());
+        assertEquals("int", cls.getFieldByName("someField").getType().getValue()); // sanity check
+        
+        //---
+
+        List<JavaField> fields = cls.getFields();
+        
+        JavaField enum1c = fields.get(0);
+        assertNull( enum1c.getComment() );
+        assertEquals( 0, enum1c.getAnnotations().size() );
+        assertEquals( "X$EnumWithConstructors", enum1c.getType().getBinaryName() );
+        assertEquals( "X.EnumWithConstructors", enum1c.getType().getFullyQualifiedName() );
+        assertEquals( "c", enum1c.getName() );
+
+        //---
+        
+        JavaField enum1d = fields.get(1);
+        assertNull( enum1d.getComment() );
+        assertEquals( "X$EnumWithConstructors", enum1d.getType().getBinaryName() );
+        assertEquals( "X.EnumWithConstructors", enum1d.getType().getFullyQualifiedName() );
         assertEquals( "d", enum1d.getName() );
 
         //---
diff --git a/src/test/java/com/thoughtworks/qdox/GenericsTest.java b/src/test/java/com/thoughtworks/qdox/GenericsTest.java
index e252279..8c044ef 100644
--- a/src/test/java/com/thoughtworks/qdox/GenericsTest.java
+++ b/src/test/java/com/thoughtworks/qdox/GenericsTest.java
@@ -279,7 +279,7 @@ public class GenericsTest extends TestCase {
         builder.addSource( new StringReader( superSource ) );
         builder.addSource( new StringReader( subSource ) );
         JavaMethod method = builder.getClassByName( "StringTest" ).getMethodBySignature( "getValue", null, true );
-        assertEquals( "T", method.getGenericReturnType().getFullyQualifiedName() );
+        assertEquals( "T", method.getReturnType(false).getValue() );
         assertEquals( "java.lang.Object", method.getReturnType().getFullyQualifiedName() );
         assertEquals( "java.lang.Object", method.getReturnType( false ).getFullyQualifiedName() );
         assertEquals( "java.lang.String", method.getReturnType( true ).getFullyQualifiedName() );
diff --git a/src/test/java/com/thoughtworks/qdox/JavaProjectBuilderTest.java b/src/test/java/com/thoughtworks/qdox/JavaProjectBuilderTest.java
index 5ab3adc..cfac48f 100644
--- a/src/test/java/com/thoughtworks/qdox/JavaProjectBuilderTest.java
+++ b/src/test/java/com/thoughtworks/qdox/JavaProjectBuilderTest.java
@@ -12,21 +12,16 @@ import java.io.IOException;
 import java.io.NotSerializableException;
 import java.io.Reader;
 import java.io.StringReader;
-import java.lang.reflect.Method;
-import java.lang.reflect.TypeVariable;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import junit.framework.TestCase;
-
 import com.thoughtworks.qdox.library.ClassLibraryBuilder;
 import com.thoughtworks.qdox.library.ErrorHandler;
 import com.thoughtworks.qdox.library.OrderedClassLibraryBuilder;
@@ -48,6 +43,8 @@ import com.thoughtworks.qdox.model.util.SerializationUtils;
 import com.thoughtworks.qdox.parser.ParseException;
 import com.thoughtworks.qdox.testdata.PropertyClass;
 
+import junit.framework.TestCase;
+
 public class JavaProjectBuilderTest extends TestCase
 {
 
@@ -127,7 +124,8 @@ public class JavaProjectBuilderTest extends TestCase
         assertEquals(1, outer.getNestedClasses().size());
         JavaClass inner = outer.getNestedClasses().get(0);
         assertEquals("Inner", inner.getName());
-        assertEquals("foo.bar.Outer$Inner", inner.getFullyQualifiedName());
+        assertEquals("foo.bar.Outer$Inner", inner.getBinaryName());
+        assertEquals("foo.bar.Outer.Inner", inner.getFullyQualifiedName());
 
         assertEquals(1, inner.getMethods().size());
         assertEquals("innerMethod", inner.getMethods().get(0).getName());
@@ -674,11 +672,13 @@ public class JavaProjectBuilderTest extends TestCase
         builder.addSource(new StringReader(source));
         JavaClass outer = builder.getClassByName("foo.Outer");
         JavaClass inner = outer.getNestedClasses().get(0);
-        assertEquals("foo.Outer$Inner", inner.getFullyQualifiedName());
+        assertEquals("foo.Outer$Inner", inner.getBinaryName());
+        assertEquals("foo.Outer.Inner", inner.getFullyQualifiedName());
 
         JavaField field1 = outer.getFieldByName("field1");
         JavaClass type = field1.getType();
-        assertEquals("foo.Outer$Inner", type.getFullyQualifiedName());
+        assertEquals("foo.Outer$Inner", type.getBinaryName());
+        assertEquals("foo.Outer.Inner", type.getFullyQualifiedName());
     }
 
     public void testJiraQdox16() {
@@ -830,10 +830,10 @@ public class JavaProjectBuilderTest extends TestCase
         String sourceCode = "package pack; public class Foo extends Bar implements Zap {}";
         builder.addSource(new StringReader(sourceCode));
         JavaClass clazz = builder.getClassByName("pack.Foo");
-        assertEquals(1, clazz.getImplementedInterfaces().size());
+        assertEquals(1, clazz.getInterfaces().size());
         // Ideally the fully qualified names should be the pack.Zap and pack.Bar,
         // but this will do for now to fix the NPE bug.
-        assertEquals("Zap", clazz.getImplementedInterfaces().get(0).getFullyQualifiedName());
+        assertEquals("Zap", clazz.getInterfaces().get(0).getFullyQualifiedName());
         assertEquals("Bar", clazz.getSuperJavaClass().getFullyQualifiedName());
     }
 
@@ -901,7 +901,8 @@ public class JavaProjectBuilderTest extends TestCase
         JavaField innerField = 
             builder.getClassByName("p2.B").getFieldByName("innerField");
         assertEquals(innerClass, innerField.getType() );
-        assertEquals("p1.A$Inner", innerField.getType().getFullyQualifiedName());
+        assertEquals("p1.A$Inner", innerField.getType().getBinaryName());
+        assertEquals("p1.A.Inner", innerField.getType().getFullyQualifiedName());
     }
 
     public void testJiraQdox71() {
@@ -1476,7 +1477,7 @@ public class JavaProjectBuilderTest extends TestCase
         assertEquals( 1, qDoxConstructor.getParameters().size() );
         JavaParameter qDoxParameter = qDoxConstructor.getParameters().get( 0 );
         assertEquals( "apiPath", qDoxParameter.getName() );
-        assertEquals( qDoxConstructor, qDoxParameter.getDeclarator() );
+        assertEquals( qDoxConstructor, qDoxParameter.getExecutable() );
     }
     
     // for QDOX-255
@@ -1502,10 +1503,12 @@ public class JavaProjectBuilderTest extends TestCase
         assertEquals( "com.foo.Outer", cls.getFullyQualifiedName() );
         assertEquals( "com.foo.Outer", cls.getCanonicalName() );
         cls = cls.getNestedClassByName( "Inner" );
-        assertEquals( "com.foo.Outer$Inner", cls.getFullyQualifiedName() );
+        assertEquals( "com.foo.Outer$Inner", cls.getBinaryName() );
+        assertEquals( "com.foo.Outer.Inner", cls.getFullyQualifiedName() );
         assertEquals( "com.foo.Outer.Inner", cls.getCanonicalName() );
         cls = cls.getNestedClassByName( "Core" );
-        assertEquals( "com.foo.Outer$Inner$Core", cls.getFullyQualifiedName() );
+        assertEquals( "com.foo.Outer$Inner$Core", cls.getBinaryName() );
+        assertEquals( "com.foo.Outer.Inner.Core", cls.getFullyQualifiedName() );
         assertEquals( "com.foo.Outer.Inner.Core", cls.getCanonicalName() );
     }
     
@@ -1551,8 +1554,116 @@ public class JavaProjectBuilderTest extends TestCase
         builder.addSource( new StringReader( source ) ); 
     }
     
+    public void testFQNField() throws Exception
+    {
+        String source = "import java.text.SimpleDateFormat;\r\n" + 
+            "public class Car {\r\n" + 
+            "    private java.text.SimpleDateFormat format;\r\n" + 
+            "}";
+        
+        JavaProjectBuilder builder = new JavaProjectBuilder();
+        builder.addSource(new StringReader( source ));
+        JavaField field = builder.getClassByName("Car").getFieldByName("format");
+        assertEquals( "java.text.SimpleDateFormat", field.getType().getFullyQualifiedName());
+    }
+    
+    // Github #12
+    public void testSamePackage() {
+        String source = "package com.fg.rtdoc.test;\n" + 
+            "public class Test extends Extend implements Iface {}";
+        
+        String iface = "package com.fg.rtdoc.test;\n" + 
+                        "public interface Iface {}";
+
+        JavaProjectBuilder builder = new JavaProjectBuilder();
+        builder.addSource(new StringReader( iface ));
+        JavaClass clz = builder.addSource(new StringReader( source )).getClassByName( "Test" );
+        
+        assertEquals( "com.fg.rtdoc.test.Iface", clz.getInterfaces().get(0).getFullyQualifiedName() );
+    }
+
+    // Github #16
+    public void testBeanProperties()
+    {
+        String zothParent = "public class ZothParent {\n" + 
+            " private String name;\n" + 
+            " public String getName() {\n" + 
+            "    return name;\n" + 
+            " }\n" + 
+            " public void setName(String name) {\n" + 
+            "    this.name = name;\n" + 
+            " }\n" + 
+            "}";
+        
+        String zothChild = "public class ZothChild // extends ZothParent\n" + 
+            "{\n" + 
+            " private int age;\n" + 
+            " public int getAge() {\n" + 
+            "    return age;\n" + 
+            " }\n" + 
+            " public void setAge(int age) {\n" + 
+            "    this.age = age;\n" + 
+            " }\n" + 
+            "}";
+        
+        JavaProjectBuilder builder = new JavaProjectBuilder();
+        builder.addSource(new StringReader( zothParent ));
+        JavaClass zothClass = builder.addSource(new StringReader( zothChild )).getClassByName( "ZothChild" );
+        assertEquals( "java.lang.Object", zothClass.getSuperClass().getBinaryName());
+        assertEquals( 2, zothClass.getBeanProperties( true ).size() );
+        
+    }
+    
+    public void testDeclarationSignatureWithGenerics() {
+        String source = "import java.util.List;"
+            + "public interface Test {"
+            + "  public List<com.amaral.model.EntityModel> findById(java.lang.Long id);"
+            + "}";
+        
+        String model = "package com.amaral.model;"
+            + "public class EntityModel {}";
+        
+        JavaProjectBuilder builder = new JavaProjectBuilder();
+        builder.addSource(new StringReader( source ));
+        builder.addSource(new StringReader( model ));
+        
+        JavaMethod findById = builder.getClassByName( "Test" ).getMethods().get(0);
+        assertEquals( "public java.util.List<com.amaral.model.EntityModel> findById(java.lang.Long id)", findById.getDeclarationSignature( true ) );
+    }
     
+    public void testOneLineJavadoc() throws Exception
+    {
+        String source = "package foo.bar;\n" + 
+            "/***/\n" + 
+            "public class MyClass{\n" + 
+            "} ";
+        builder.addSource( new StringReader( source ) ); 
+    }
     
+    public void testMethodReferences() throws Exception
+    {
+        String source = "public enum AmazonClients {\n" + 
+            "    ECS(AmazonECSClient::new),\n" + 
+            "    ECR(AmazonECRClient::new);\n"
+            + "}";
+
+        builder.addSource( new StringReader( source ) ); 
+    }
+    
+    public void testAnonymousEnumConstructor() throws Exception
+    {
+        String source = "package parent;\n" + 
+            "public enum MyEnum {\n" + 
+            "    VALUE(new Runnable() {\n" + 
+            "        @Override\n" + 
+            "        public void run() { }\n" + 
+            "    });\n" + 
+            "    MyEnum(Runnable function) { }\n" + 
+            "}";
+        
+        builder.addSource( new StringReader( source ) ); 
+    }
+
     public void testSetDebugLexer()
     {
         ClassLibraryBuilder classLibraryBuilder = mock( ClassLibraryBuilder.class );
@@ -1665,6 +1776,6 @@ public class JavaProjectBuilderTest extends TestCase
         builder = new JavaProjectBuilder( classLibraryBuilder );
         builder.addSourceFolder( file );
         
-        verify( classLibraryBuilder ).appendSourceFolder( same( file ) );
+        verify( classLibraryBuilder ).addSourceFolder( same( file ) );
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitorTest.java b/src/test/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitorTest.java
index fd65711..a2592c7 100644
--- a/src/test/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitorTest.java
+++ b/src/test/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitorTest.java
@@ -10,17 +10,12 @@ import static org.mockito.Mockito.when;
 import java.util.Collections;
 import java.util.List;
 
-import org.junit.Ignore;
 import org.junit.Test;
 
 import com.thoughtworks.qdox.library.ClassLibrary;
-import com.thoughtworks.qdox.model.JavaAnnotatedElement;
 import com.thoughtworks.qdox.model.JavaAnnotation;
 import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaField;
-import com.thoughtworks.qdox.model.JavaMethod;
-import com.thoughtworks.qdox.model.JavaPackage;
-import com.thoughtworks.qdox.model.JavaParameter;
 import com.thoughtworks.qdox.model.JavaType;
 import com.thoughtworks.qdox.model.expression.Add;
 import com.thoughtworks.qdox.model.expression.And;
@@ -52,7 +47,6 @@ import com.thoughtworks.qdox.model.expression.ShiftRight;
 import com.thoughtworks.qdox.model.expression.Subtract;
 import com.thoughtworks.qdox.model.expression.TypeRef;
 import com.thoughtworks.qdox.model.expression.UnsignedShiftRight;
-import com.thoughtworks.qdox.model.impl.DefaultJavaAnnotation;
 
 public class EvaluatingVisitorTest
 {
@@ -505,9 +499,7 @@ public class EvaluatingVisitorTest
     @Test
     public void testVisitFieldRef() 
     {
-        JavaAnnotatedElement annotatedElement = mock( JavaAnnotatedElement.class );
         FieldRef ref = new FieldRef( "fieldname" );
-        ref.setContext( annotatedElement );
         try {
             visitor.visit( ref );
             fail( "fieldname should be a unresolvable field" );
@@ -522,6 +514,7 @@ public class EvaluatingVisitorTest
         when( declaringClass.getFieldByName( "fieldname" ) ).thenReturn( nonStaticNonFinalfield );
 
         JavaClass annotatedClass = mock( JavaClass.class );
+        ref.setDeclaringClass( declaringClass );
         try 
         {
             visitor.visit(  ref );
@@ -538,31 +531,21 @@ public class EvaluatingVisitorTest
         when( declaringClass.getFieldByName( "fieldname" ) ).thenReturn( staticFinalfield );
 
         ref = new FieldRef( "fieldname" );
-        ref.setContext( annotatedClass );
-        when( annotatedClass.getDeclaringClass() ).thenReturn( declaringClass );
+        ref.setDeclaringClass( declaringClass );
         assertSame( EvaluatingVisitorStub.fieldReferenceValue, visitor.visit( ref ) );
 
-        JavaMethod annotatedMethod = mock( JavaMethod.class );
         ref = new FieldRef( "fieldname" );
-        ref.setContext( annotatedMethod );
-        when( annotatedMethod.getDeclaringClass() ).thenReturn( declaringClass );
+        ref.setDeclaringClass( declaringClass );
         assertSame( EvaluatingVisitorStub.fieldReferenceValue, visitor.visit( ref ) );
 
-        JavaParameter annotatedParameter = mock( JavaParameter.class );
-        ref = new FieldRef( "fieldname" );
-        ref.setContext( annotatedParameter );
-        when( annotatedParameter.getParentClass() ).thenReturn( declaringClass );
-        assertSame( EvaluatingVisitorStub.fieldReferenceValue, visitor.visit( ref ) );
-        
-        JavaPackage annotatedPackage = mock( JavaPackage.class );
         ref = new FieldRef( "a.B.fieldname" );
-        ref.setContext( annotatedPackage );
+        ref.setDeclaringClass( null );
         JavaClass b = mock( JavaClass.class );
         when( b.getFieldByName( "fieldname" ) ).thenReturn( staticFinalfield );
         ClassLibrary classLibrary = mock( ClassLibrary.class );
         when( classLibrary.hasClassReference( "a.B" ) ).thenReturn( true );
         when( classLibrary.getJavaClass( "a.B" ) ).thenReturn( b );
-        when( annotatedPackage.getJavaClassLibrary() ).thenReturn( classLibrary );
+        ref.setClassLibrary( classLibrary );
         assertSame( EvaluatingVisitorStub.fieldReferenceValue, visitor.visit( ref ) );
     }
     
diff --git a/src/test/java/com/thoughtworks/qdox/builder/impl/ModelBuilderTest.java b/src/test/java/com/thoughtworks/qdox/builder/impl/ModelBuilderTest.java
index b994797..3945c13 100644
--- a/src/test/java/com/thoughtworks/qdox/builder/impl/ModelBuilderTest.java
+++ b/src/test/java/com/thoughtworks/qdox/builder/impl/ModelBuilderTest.java
@@ -310,7 +310,8 @@ public class ModelBuilderTest extends TestCase {
         assertEquals("bar", outerClass.getMethods().get(0).getName());
         assertEquals(1, outerClass.getNestedClasses().size());
         JavaClass innerClass = outerClass.getNestedClasses().get(0);
-        assertEquals("xyz.Outer$Inner", innerClass.getFullyQualifiedName());
+        assertEquals("xyz.Outer$Inner", innerClass.getBinaryName());
+        assertEquals("xyz.Outer.Inner", innerClass.getFullyQualifiedName());
         assertEquals(1, innerClass.getMethods().size());
         assertEquals("foo", innerClass.getMethods().get(0).getName());
     }
@@ -328,8 +329,6 @@ public class ModelBuilderTest extends TestCase {
         JavaMethod doSomething = source.getClasses().get(0).getMethods().get(0);
         assertEquals("doSomething", doSomething.getName());
         assertEquals("void", doSomething.getReturns().getValue());
-        JavaSource parentSource = doSomething.getReturns().getParent().getParentSource();
-        assertSame(source, parentSource);
         assertEquals(0, doSomething.getModifiers().size());
         assertEquals(0, doSomething.getParameters().size());
         assertEquals(0, doSomething.getExceptions().size());
diff --git a/src/test/java/com/thoughtworks/qdox/library/AbstractClassLibraryTest.java b/src/test/java/com/thoughtworks/qdox/library/AbstractClassLibraryTest.java
index c955ca4..b04d521 100644
--- a/src/test/java/com/thoughtworks/qdox/library/AbstractClassLibraryTest.java
+++ b/src/test/java/com/thoughtworks/qdox/library/AbstractClassLibraryTest.java
@@ -137,4 +137,12 @@ public class AbstractClassLibraryTest
         assertEquals( null, nullClassLibrary.getJavaPackage( "java.lang" ) );
         assertEquals( null, nullClassLibrary.getJavaPackage( "com.thoughtworks" ) );
     }
+    
+    public void testModuleInfo()
+    {
+        assertNull( nullClassLibrary.getJavaModules() );
+        assertNull( parentClassLibrary.getJavaModules() );
+        assertNull( filledChildClassLibrary.getJavaModules() );
+        assertNull( emptyChildClassLibrary.getJavaModules() );
+    }
 }
diff --git a/src/test/java/com/thoughtworks/qdox/library/ClassLibraryBuilderTest.java b/src/test/java/com/thoughtworks/qdox/library/ClassLibraryBuilderTest.java
index 318daac..9b4d383 100644
--- a/src/test/java/com/thoughtworks/qdox/library/ClassLibraryBuilderTest.java
+++ b/src/test/java/com/thoughtworks/qdox/library/ClassLibraryBuilderTest.java
@@ -35,14 +35,15 @@ public abstract class ClassLibraryBuilderTest
     public final void testAppendSourceInputStream() throws Exception
     {
         ClassLibraryBuilder libraryBuilder = getClassLibraryBuilder();
-        ClassLibraryBuilder result = libraryBuilder.appendSource( new ByteArrayInputStream( new byte[]{} ) );
+        ClassLibraryBuilder result =
+            libraryBuilder.appendSource( new ByteArrayInputStream( "package x.y.z;".getBytes( "UTF-8" ) ) );
         assertSame( libraryBuilder, result );
     }
 
     public final void testAppendSourceReader() throws Exception
     {
         ClassLibraryBuilder libraryBuilder = getClassLibraryBuilder();
-        ClassLibraryBuilder result = libraryBuilder.appendSource( new StringReader("") );
+        ClassLibraryBuilder result = libraryBuilder.appendSource( new StringReader("package x.y.z;") );
         assertSame( libraryBuilder, result );
     }
 
diff --git a/src/test/java/com/thoughtworks/qdox/library/ClassLoaderLibraryTest.java b/src/test/java/com/thoughtworks/qdox/library/ClassLoaderLibraryTest.java
index 0b73387..a316b29 100644
--- a/src/test/java/com/thoughtworks/qdox/library/ClassLoaderLibraryTest.java
+++ b/src/test/java/com/thoughtworks/qdox/library/ClassLoaderLibraryTest.java
@@ -33,4 +33,8 @@ public class ClassLoaderLibraryTest
         assertNull(classLoaderLibrary.getJavaClass("java.util.GoatCrusher"));
     }
 
+    public void testModuleInfo() throws Exception
+    {
+        assertNull( classLoaderLibrary.getJavaModules() );
+    }
 }
diff --git a/src/test/java/com/thoughtworks/qdox/library/SourceFolderLibraryTest.java b/src/test/java/com/thoughtworks/qdox/library/SourceFolderLibraryTest.java
new file mode 100644
index 0000000..c979e14
--- /dev/null
+++ b/src/test/java/com/thoughtworks/qdox/library/SourceFolderLibraryTest.java
@@ -0,0 +1,112 @@
+package com.thoughtworks.qdox.library;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.StringReader;
+import java.util.Iterator;
+
+import org.junit.Test;
+
+import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaModule;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaExports;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaOpens;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaProvides;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaRequires;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaUses;
+
+public class SourceFolderLibraryTest
+{
+    private SourceFolderLibrary library = new SourceFolderLibrary( null );
+
+    @Test
+    public void testClassisFolder() {
+        JavaModule directModule = library.addSourceFolder( new File("src/test/resources/qdox-140") ); 
+        assertEquals( null, directModule);
+    }
+    
+    @Test
+    public void testModuleInfo()
+    {
+        library.addSource( new StringReader("package V;\n"
+                        + "public interface W {}") );
+        library.addSource( new StringReader("package X;\n"
+                        + "public interface Y {}") );
+        library.addSource( new StringReader("package Z1;\n"
+                        + "public class Z2 implements X.Y {}") );
+        library.addSource( new StringReader("package Z3;\n"
+                        + "public class Z4 implements X.Y {}") );
+        
+        JavaModule directModule = library.addSourceFolder( new File("src/test/resources/jigsaw/example1") );
+        assertEquals( "M.N", directModule.getName() );
+        
+        JavaModule module = library.getJavaModules().iterator().next();
+        assertEquals( "M.N", module.getName() );
+        JavaModuleDescriptor descriptor = module.getDescriptor();
+        assertEquals( 4, descriptor.getRequires().size() );
+        Iterator<JavaRequires> requiresIter = descriptor.getRequires().iterator();
+        JavaRequires req = requiresIter.next();
+        assertEquals( "A.B", req.getModule().getName() );
+        assertEquals( false, req.isTransitive() );
+        assertEquals( false, req.isStatic() );
+        req = requiresIter.next();
+        assertEquals( "C.D", req.getModule().getName() );
+        assertEquals( true, req.isTransitive() );
+        assertEquals( false, req.isStatic() );
+        req = requiresIter.next();
+        assertEquals( "E.F", req.getModule().getName() );
+        assertEquals( false, req.isTransitive() );
+        assertEquals( true, req.isStatic() );
+        req = requiresIter.next();
+        assertEquals( "G.H", req.getModule().getName() );
+        assertEquals( true, req.isTransitive() );
+        assertEquals( true, req.isStatic() );
+        
+        assertEquals( 2, module.getDescriptor().getExports().size());
+        Iterator<JavaExports> exportsIter = descriptor.getExports().iterator();
+        JavaExports exp = exportsIter.next();
+        assertEquals( "P.Q", exp.getSource().getName() );
+        assertArrayEquals( new String[0], exp.getTargets().toArray( new String[0] ) );
+        exp = exportsIter.next();
+        assertEquals( "R.S", exp.getSource().getName() );
+        assertEquals( 2, exp.getTargets().size());
+        Iterator<JavaModule> moduleIter = exp.getTargets().iterator();
+        JavaModule mdl = moduleIter.next();
+        assertEquals( "T1.U1", mdl.getName() );
+        mdl = moduleIter.next();
+        assertEquals( "T2.U2", mdl.getName() );
+        
+        assertEquals( 2, module.getDescriptor().getOpens().size() );
+        Iterator<JavaOpens> opensIter = descriptor.getOpens().iterator();
+        JavaOpens opn = opensIter.next();
+        assertEquals( "P.Q", opn.getSource().getName() );
+        assertArrayEquals( new String[0], opn.getTargets().toArray( new String[0] ) );
+        opn = opensIter.next();
+        assertEquals( "R.S", opn.getSource().getName() );
+        assertEquals( 2, opn.getTargets().size());
+        moduleIter = opn.getTargets().iterator();
+        mdl = moduleIter.next();
+        assertEquals( "T1.U1", mdl.getName() );
+        mdl = moduleIter.next();
+        assertEquals( "T2.U2", mdl.getName() );
+        
+        assertEquals( 1, module.getDescriptor().getUses().size() );
+        Iterator<JavaUses> usesIter = descriptor.getUses().iterator();
+        JavaUses uses = usesIter.next();
+        assertEquals( "V.W", uses.getService().getFullyQualifiedName() );
+        
+        assertEquals( 1, module.getDescriptor().getProvides().size() );
+        Iterator<JavaProvides> providesIter = descriptor.getProvides().iterator();
+        JavaProvides provides = providesIter.next();
+        assertEquals( "X.Y", provides.getService().getFullyQualifiedName() );
+        Iterator<JavaClass> classIter = provides.getProviders().iterator(); 
+        JavaClass cls = classIter.next();
+        assertEquals( "Z1.Z2", cls.getFullyQualifiedName() );
+        cls = classIter.next();
+        assertEquals( "Z3.Z4", cls.getFullyQualifiedName() );
+    }
+    
+}
diff --git a/src/test/java/com/thoughtworks/qdox/library/SourceLibraryTest.java b/src/test/java/com/thoughtworks/qdox/library/SourceLibraryTest.java
index 87b8032..3438965 100644
--- a/src/test/java/com/thoughtworks/qdox/library/SourceLibraryTest.java
+++ b/src/test/java/com/thoughtworks/qdox/library/SourceLibraryTest.java
@@ -104,5 +104,10 @@ public class SourceLibraryTest
         assertEquals("TEST-CHARS: \u00C4\u00D6\u00DC\u00E4\u00F6\u00FC\u00DF", src.getClassByName( "Latin1" ).getComment());
     }
 
+    public void testModuleInfo() throws Exception {
+    	File file = new File( "src/test/resources/com/thoughtworks/qdox/testdata/module-info.java");
+    	assertNull( "module-info.java should be ignored", sourceLibrary.addSource(file) );
+    	assertNull( sourceLibrary.getJavaModules() );
+    }
     
 }
diff --git a/src/test/java/com/thoughtworks/qdox/model/JavaClassTest.java b/src/test/java/com/thoughtworks/qdox/model/JavaClassTest.java
index 471d473..14cf7a3 100644
--- a/src/test/java/com/thoughtworks/qdox/model/JavaClassTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/JavaClassTest.java
@@ -500,20 +500,15 @@ public abstract class JavaClassTest<C extends JavaClass> {
         setName(cls, "MyClass");
 
         assertEquals("MyClass", cls.getName());
+        assertEquals("MyClass", cls.getSimpleName());
         assertEquals("com.thoughtworks.qdox", cls.getPackage().getName());
         assertEquals("com.thoughtworks.qdox", cls.getPackageName());
-        assertEquals("com.thoughtworks.qdox.MyClass",
-                cls.getFullyQualifiedName());
+        assertEquals("com.thoughtworks.qdox.MyClass", cls.getBinaryName());
+        assertEquals("com.thoughtworks.qdox.MyClass", cls.getCanonicalName());
+        assertEquals("com.thoughtworks.qdox.MyClass", cls.getFullyQualifiedName());
     }
 
     @Test
-    public void testGetClassNamePrefix() {
-        setPackage(src, newJavaPackage("foo.bar"));
-        setName(cls, "Stanley");
-        assertEquals("foo.bar.Stanley$", cls.getClassNamePrefix());
-    }
-    
-    @Test
     public void testInnerClass() throws Exception
     {
         JavaPackage pkg = mock(JavaPackage.class);
@@ -522,21 +517,20 @@ public abstract class JavaClassTest<C extends JavaClass> {
         JavaClass outer = mock( JavaClass.class );
         when( outer.getName() ).thenReturn( "Outer" );
         when( outer.getPackageName() ).thenReturn( "foo.bar" );
-        when( outer.getClassNamePrefix() ).thenReturn( "foo.bar.Outer$" );
+        when( outer.getFullyQualifiedName() ).thenReturn( "foo.bar.Outer" );
+        when( outer.getBinaryName() ).thenReturn( "foo.bar.Outer" );
 
         C inner = newJavaClass();
         setName(inner, "Inner");
         setPackage( inner, pkg );
         setDeclaringClass( inner, outer );
         
-        
         assertEquals("Inner", inner.getName());
+        assertEquals("Inner", inner.getSimpleName());
         assertEquals("foo.bar", inner.getPackageName());
-        assertEquals("foo.bar.Outer$Inner", inner.getFullyQualifiedName());
-        
-        assertEquals("Inner", inner.getName());
-        assertEquals("foo.bar", inner.getPackageName());
-        assertEquals("foo.bar.Outer$Inner", inner.getFullyQualifiedName());
+        assertEquals("foo.bar.Outer$Inner", inner.getBinaryName());
+        assertEquals("foo.bar.Outer.Inner", inner.getCanonicalName());
+        assertEquals("foo.bar.Outer.Inner", inner.getFullyQualifiedName());
     }
     
     @Test
@@ -675,29 +669,6 @@ public abstract class JavaClassTest<C extends JavaClass> {
     }
 
     @Test
-    public void testResolveTypeDefaultsToParentScope()
-        throws Exception
-    {
-        setName( cls, "X" );
-        assertEquals( "int", cls.resolveType( "int" ) );
-        assertEquals( "int", cls.resolveCanonicalName( "int" ) );
-        assertEquals( "int", cls.resolveFullyQualifiedName( "int" ) );
-    }
-    
-    @Test
-    public void testResolveTypeInnerClass() throws Exception {
-        setPackage(src, newJavaPackage("p"));
-        setName(cls, "X");
-        JavaClass innerClass = mock(JavaClass.class );
-        when( innerClass.getName() ).thenReturn( "DogFood" );
-        when( innerClass.getFullyQualifiedName() ).thenReturn( "p.X$DogFood" );
-        setClasses(cls, Collections.singletonList( innerClass ) );
-        
-        assertEquals("p.X$DogFood", cls.resolveType("DogFood"));
-        assertEquals(null, cls.resolveType("Food"));
-    }
-
-    @Test
     public void testGetBeanPropertiesReturnsEmptyForEmptyClass() throws Exception {
         assertEquals(0, cls.getBeanProperties().size());
     }
@@ -742,35 +713,35 @@ public abstract class JavaClassTest<C extends JavaClass> {
     @Test
     public void testInnerClassToString() throws Exception {
     	JavaClass jOuterClass = mock(JavaClass.class);
-    	when(jOuterClass.getClassNamePrefix()).thenReturn( "com.thoughtworks.qdox.model.OuterClass$" );
+    	when(jOuterClass.getFullyQualifiedName()).thenReturn( "com.thoughtworks.qdox.model.OuterClass" );
     	
         C jInnerClass = newJavaClass( "InnerClass" );
     	setDeclaringClass( jInnerClass, jOuterClass );
     	
-    	assertEquals("class com.thoughtworks.qdox.model.OuterClass$InnerClass", jInnerClass.toString());
+    	assertEquals("class com.thoughtworks.qdox.model.OuterClass.InnerClass", jInnerClass.toString());
     }
     
     @Test
     public void testInnerClassType() {
         JavaClass jOuterClass = mock(JavaClass.class);
-        when(jOuterClass.getClassNamePrefix()).thenReturn("com.thoughtworks.qdox.model.OuterClass$");
+        when(jOuterClass.getFullyQualifiedName()).thenReturn("com.thoughtworks.qdox.model.OuterClass");
 
         C jInnerClass = newJavaClass("InnerClass");
         setDeclaringClass( jInnerClass, jOuterClass );
         
-        assertEquals( "com.thoughtworks.qdox.model.OuterClass$InnerClass", jInnerClass.getFullyQualifiedName() );
+        assertEquals( "com.thoughtworks.qdox.model.OuterClass.InnerClass", jInnerClass.getFullyQualifiedName() );
     }
     
     @Test
     public void testInnerInterfaceToString() {
     	JavaClass jOuterClass = mock(JavaClass.class);
-    	when(jOuterClass.getClassNamePrefix()).thenReturn( "com.thoughtworks.qdox.model.OuterClass$");
+    	when(jOuterClass.getFullyQualifiedName()).thenReturn( "com.thoughtworks.qdox.model.OuterClass");
 
     	C jInnerInterface = newJavaClass( "InnerInterface" );
     	setInterface( jInnerInterface, true );
         setDeclaringClass( jInnerInterface, jOuterClass );
         
-    	assertEquals("interface com.thoughtworks.qdox.model.OuterClass$InnerInterface", jInnerInterface.toString());
+    	assertEquals("interface com.thoughtworks.qdox.model.OuterClass.InnerInterface", jInnerInterface.toString());
     }
     
     @Test
diff --git a/src/test/java/com/thoughtworks/qdox/model/JavaConstructorTest.java b/src/test/java/com/thoughtworks/qdox/model/JavaConstructorTest.java
index 56e4804..3fb1ff1 100644
--- a/src/test/java/com/thoughtworks/qdox/model/JavaConstructorTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/JavaConstructorTest.java
@@ -17,7 +17,7 @@ public abstract class JavaConstructorTest<D extends JavaConstructor>
     protected abstract D newJavaConstructor( String string );    
 
     protected abstract void setModifiers( D constructor, List<String> asList );
-    protected abstract void setParentClass( D constructor, JavaClass cls );
+    protected abstract void setDeclaringClass( D constructor, JavaClass cls );
     protected abstract void setParameters( D constructor, List<JavaParameter> singletonList );
 
     private JavaType newType( String name )
@@ -54,7 +54,7 @@ public abstract class JavaConstructorTest<D extends JavaConstructor>
         JavaClass cls = mock(JavaClass.class);
         when(cls.getFullyQualifiedName()).thenReturn( "a.b.Executor" );
         D constructor = newJavaConstructor( "Executor" );
-        setParentClass( constructor, cls );
+        setDeclaringClass( constructor, cls );
         assertEquals("a.b.Executor()", constructor.toString());
     }
 
@@ -64,7 +64,7 @@ public abstract class JavaConstructorTest<D extends JavaConstructor>
         when(cls.getFullyQualifiedName()).thenReturn( "a.b.Executor" );
         D constructor = newJavaConstructor( "Executor" );
         setParameters( constructor,  Collections.singletonList( newJavaParameter( newType("a.b.C"), "param" )  ));
-        setParentClass( constructor, cls );
+        setDeclaringClass( constructor, cls );
         assertEquals("a.b.C", constructor.getParameterTypes().get(0).getFullyQualifiedName());
     }
     
@@ -87,7 +87,7 @@ public abstract class JavaConstructorTest<D extends JavaConstructor>
         D c3 = newJavaConstructor( "Thong" );
 
         D c4 = newJavaConstructor( "Thong" );
-        setParentClass( c4, mock( JavaClass.class ) );
+        setDeclaringClass( c4, mock( JavaClass.class ) );
 
         assertEquals( c1, c1 );
         assertThat( c1, not( new Object() ) );
diff --git a/src/test/java/com/thoughtworks/qdox/model/JavaFieldTest.java b/src/test/java/com/thoughtworks/qdox/model/JavaFieldTest.java
index aff3cb5..249550b 100644
--- a/src/test/java/com/thoughtworks/qdox/model/JavaFieldTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/JavaFieldTest.java
@@ -104,30 +104,6 @@ public abstract class JavaFieldTest<F extends JavaField> extends TestCase {
         assertEquals(expected, fld.getCodeBlock());
     }
     
-    public void testShouldReturnFieldNameForCallSignature() throws Exception {
-        F fld = newJavaField();
-        setName(fld, "count");
-        setType(fld, newJavaClass("int"));
-        setModifiers(fld, Arrays.asList(new String[]{"public", "final"}));
-        assertEquals("count", fld.getCallSignature());
-    }
-
-    public void testShouldReturnProperDeclarationSignatureWithModifiers() throws Exception {
-        F fld = newJavaField();
-        setName(fld, "count");
-        setType(fld, newJavaClass("int"));
-        setModifiers(fld, Arrays.asList(new String[]{"public", "final"}));
-        assertEquals("public final int count", fld.getDeclarationSignature(true));
-    }
-
-    public void testShouldReturnProperDeclarationSignatureWithoutModifiers() throws Exception {
-        F fld = newJavaField();
-        setName(fld, "count");
-        setType(fld, newJavaClass("int"));
-        setModifiers(fld, Arrays.asList(new String[]{"public", "final"}));
-        assertEquals("int count", fld.getDeclarationSignature(false));
-    }
-    
     public void testToStringThreadMIN_PRIORITY() throws Exception {
     	JavaClass cls = mock(JavaClass.class);
     	when(cls.getFullyQualifiedName()).thenReturn( "java.lang.Thread" );
diff --git a/src/test/java/com/thoughtworks/qdox/model/JavaMethodTest.java b/src/test/java/com/thoughtworks/qdox/model/JavaMethodTest.java
index 11f4fa8..9bdeec9 100644
--- a/src/test/java/com/thoughtworks/qdox/model/JavaMethodTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/JavaMethodTest.java
@@ -16,8 +16,6 @@ import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
 
-import com.thoughtworks.qdox.model.impl.DefaultJavaType;
-
 public abstract class JavaMethodTest<M extends JavaMethod> {
 
     private M mth;
@@ -32,7 +30,7 @@ public abstract class JavaMethodTest<M extends JavaMethod> {
     public abstract void setName(M method, String name);
     public abstract void setModifiers(M method, List<String> modifiers);
     public abstract void setParameters(M method, List<JavaParameter> parameters);
-    public abstract void setParentClass(M method, JavaClass clazz);
+    public abstract void setDeclaringClass(M method, JavaClass clazz);
     public abstract void setReturns(M method, JavaClass type);
     public abstract void setSourceCode(M method, String code);
     
@@ -258,7 +256,7 @@ public abstract class JavaMethodTest<M extends JavaMethod> {
         setReturns(m8, newType("int"));
 //        JavaClass declaringClass = mock( JavaClass.class );
 //        when( declaringClass.getFullyQualifiedName() ).thenReturn( "com.foo.bar" );
-        setParentClass( m8, mock( JavaClass.class ) );
+        setDeclaringClass( m8, mock( JavaClass.class ) );
 
         assertEquals(mth, mth);
         assertThat(mth, not(new Object()));
@@ -316,7 +314,7 @@ public abstract class JavaMethodTest<M extends JavaMethod> {
     public void testHashCode()
         throws Exception
     {
-        assertTrue( "hashCode should never resolve to 0", newJavaMethod( DefaultJavaType.VOID, "" ).hashCode() != 0 );
+        assertTrue( "hashCode should never resolve to 0", newJavaMethod( newType("void"), "" ).hashCode() != 0 );
 
         JavaClass voidType = newType( "void" );
         JavaClass intType = newType( "int", 1 );
@@ -411,8 +409,8 @@ public abstract class JavaMethodTest<M extends JavaMethod> {
     @Test
     public void testParentClass() throws Exception {
         JavaClass clazz = mock(JavaClass.class);
-        setParentClass( mth, clazz );
-        assertSame(clazz, mth.getParentClass());
+        setDeclaringClass( mth, clazz );
+        assertSame(clazz, mth.getDeclaringClass());
     }
 
     @Test
@@ -427,9 +425,9 @@ public abstract class JavaMethodTest<M extends JavaMethod> {
     @Test
     public void testToString() throws Exception {
         JavaClass cls = mock(JavaClass.class);
-        when(cls.getFullyQualifiedName()).thenReturn( "java.lang.Object" );
+        when(cls.getBinaryName()).thenReturn( "java.lang.Object" );
     	M mthd = newJavaMethod(newType("boolean"),"equals");
-    	setParentClass(mthd, cls);
+    	setDeclaringClass(mthd, cls);
     	setModifiers(mthd, Arrays.asList(new String[]{"public"}));
     	setParameters(mthd, Collections.singletonList( newJavaParameter(newType("java.lang.Object"), null) ));
     	assertEquals("public boolean java.lang.Object.equals(java.lang.Object)", mthd.toString());
@@ -561,18 +559,18 @@ public abstract class JavaMethodTest<M extends JavaMethod> {
     @Test
     public void testIsPropertyMutator()
     {
-        M setNameMethod = newJavaMethod( DefaultJavaType.VOID, "setName" );
+        M setNameMethod = newJavaMethod( newType("void"), "setName" );
         setParameters( setNameMethod, Collections.singletonList( mock(JavaParameter.class) ) );
         assertTrue( setNameMethod.isPropertyMutator() );
 
-        M setUpMethod = newJavaMethod( DefaultJavaType.VOID, "setUp" );
+        M setUpMethod = newJavaMethod( newType("void"), "setUp" );
         assertFalse( setUpMethod.isPropertyMutator() );
 
-        M settingUpMethod = newJavaMethod( DefaultJavaType.VOID, "settingUp" );
+        M settingUpMethod = newJavaMethod( newType("void"), "settingUp" );
         setParameters( settingUpMethod, Collections.singletonList( mock(JavaParameter.class) ) );
         assertFalse( settingUpMethod.isPropertyMutator() );
 
-        M staticSetNameMethod = newJavaMethod( DefaultJavaType.VOID, "setName" );
+        M staticSetNameMethod = newJavaMethod( newType("void"), "setName" );
         setModifiers( staticSetNameMethod, Collections.singletonList( "static" ) );
         setParameters( staticSetNameMethod, Collections.singletonList( mock(JavaParameter.class) ) );
         assertFalse( staticSetNameMethod.isPropertyMutator() );
diff --git a/src/test/java/com/thoughtworks/qdox/model/JavaParameterTest.java b/src/test/java/com/thoughtworks/qdox/model/JavaParameterTest.java
index e2c57b8..bf614fd 100644
--- a/src/test/java/com/thoughtworks/qdox/model/JavaParameterTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/JavaParameterTest.java
@@ -3,13 +3,12 @@ package com.thoughtworks.qdox.model;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import com.thoughtworks.qdox.model.impl.DefaultJavaType;
-
 import junit.framework.TestCase;
 
 public abstract class JavaParameterTest<P extends JavaParameter>
     extends TestCase
 {
+    private final JavaClass VOID = newType( "void" );
 
     public JavaParameterTest( String s )
     {
@@ -22,9 +21,7 @@ public abstract class JavaParameterTest<P extends JavaParameter>
     protected abstract P newJavaParameter( JavaClass type, String name, boolean varArgs );
 
     // setters
-    protected abstract void setMethod( P parameter, JavaMethod method );
-
-    protected abstract void setConstructor( P parameter, JavaConstructor constructor );
+    protected abstract void setJavaExecutable( P parameter, JavaExecutable executable );
 
     protected JavaClass newType( String typeName )
     {
@@ -35,46 +32,34 @@ public abstract class JavaParameterTest<P extends JavaParameter>
 
     public void testHashCode()
     {
-        assertTrue( "hashCode should never resolve to 0", newJavaParameter( DefaultJavaType.VOID, "" ).hashCode() != 0 );
+        assertTrue( "hashCode should never resolve to 0", newJavaParameter( VOID, "" ).hashCode() != 0 );
 
-        P simpleParameter = newJavaParameter( DefaultJavaType.VOID, "", false );
-        P varArgParameter = newJavaParameter( DefaultJavaType.VOID, "", true );
+        P simpleParameter = newJavaParameter( VOID, "", false );
+        P varArgParameter = newJavaParameter( VOID, "", true );
 
         assertTrue( simpleParameter.hashCode() != varArgParameter.hashCode() );
     }
 
     public void testEquals()
     {
-        P simpleParameter = newJavaParameter( DefaultJavaType.VOID, "", false );
-        P varArgParameter = newJavaParameter( DefaultJavaType.VOID, "", true );
+        P simpleParameter = newJavaParameter( VOID, "", false );
+        P varArgParameter = newJavaParameter( VOID, "", true );
         assertTrue( !simpleParameter.equals( varArgParameter ) );
 
         // name of parameter shouldn't matter
-        P fooParameter = newJavaParameter( DefaultJavaType.VOID, "foo" );
-        P barParameter = newJavaParameter( DefaultJavaType.VOID, "bar" );
+        P fooParameter = newJavaParameter( VOID, "foo" );
+        P barParameter = newJavaParameter( VOID, "bar" );
         assertEquals( fooParameter, barParameter );
     }
 
-    public void testMethodDeclarator()
+    public void testExecutableDeclarator()
         throws Exception
     {
         P p = newJavaParameter( newType( "x" ), "x" );
-        assertNull( p.getDeclarator() );
+        assertNull( p.getExecutable() );
 
-        JavaMethod m = mock( JavaMethod.class );
-        setMethod( p, m );
-        assertSame( m, p.getDeclarator() );
+        JavaExecutable e = mock( JavaExecutable.class );
+        setJavaExecutable( p, e );
+        assertSame( e, p.getExecutable() );
     }
-
-    public void testConstgructorDeclarator()
-        throws Exception
-    {
-        P p = newJavaParameter( newType( "x" ), "x" );
-        assertNull( p.getDeclarator() );
-
-        JavaConstructor c = mock( JavaConstructor.class );
-        setConstructor( p, c );
-        assertSame( c, p.getDeclarator() );
-    }
-
 }
diff --git a/src/test/java/com/thoughtworks/qdox/model/JavaSourceTest.java b/src/test/java/com/thoughtworks/qdox/model/JavaSourceTest.java
index 4ad29cb..03236c8 100644
--- a/src/test/java/com/thoughtworks/qdox/model/JavaSourceTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/JavaSourceTest.java
@@ -150,105 +150,4 @@ public abstract class JavaSourceTest<S extends JavaSource> extends TestCase {
         setPackage(source, newJavaPackage("foo.bar"));
         assertEquals("foo.bar.", source.getClassNamePrefix());
        }
-    
-    public void testResolveJavaPrimitive() throws Exception {
-        List<String> imports = new ArrayList<String>();
-        imports.add("bogus.int");
-        imports.add("bogus.double");
-        setImports( source, imports );
-        String[] primitives = new String[]{
-            "boolean", "byte", "char", "double",
-            "float", "int", "long", "short", "void"
-        };
-        for (int i = 0; i < primitives.length; i++) {
-            assertEquals(primitives[i], source.resolveType(primitives[i]));
-        }
-    }
-
-    public void testDontResolveMissingClasses() throws Exception {
-        assertEquals(null, source.resolveType("not.Found"));
-    }
-
-    public void testResolveFullyQualifiedName() throws Exception
-    {
-        assertNotNull( source.getJavaClassLibrary().getJavaClass( "open.Bar" ) );
-        assertEquals( "open.Bar", source.resolveType( "open.Bar" ) );
-    }
-    
-    public void testResolveFullyQualifiedImport() throws Exception {
-        setImports( source, Collections.singletonList( "foo.Bar" ) );
-        assertNotNull( source.getJavaClassLibrary().getJavaClass( "foo.Bar" ) );
-        assertEquals( "foo.Bar", source.resolveType( "Bar" ) );
-    }
-
-    public void testResolveChooseFirstMatchingImport() throws Exception {
-        List<String> imports = new ArrayList<String>();
-        imports.add( "bogus.package.MyType" );
-        imports.add( "com.thoughtworks.qdox.model.Type" );
-        imports.add( "another.package.Type" );
-        setImports( source, imports );
-        assertNotNull( source.getJavaClassLibrary().getJavaClass( "bogus.package.MyType" ) );
-        assertNotNull( source.getJavaClassLibrary().getJavaClass( "com.thoughtworks.qdox.model.Type" ) );
-        assertNotNull( source.getJavaClassLibrary().getJavaClass( "another.package.Type" ) );
-        assertEquals( "com.thoughtworks.qdox.model.Type", source.resolveType( "Type" ) );
-    }
-
-    public void testResolveSamePackage() throws Exception {
-        setPackage(source, newJavaPackage("foo"));
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("foo.Bar") );
-        assertEquals("foo.Bar", source.resolveType("Bar"));
-    }
-
-    public void testResolveFullyQualifiedTrumpsSamePackage() throws Exception {
-        setPackage(source, newJavaPackage("foo"));
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("foo.Bar") );
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("open.Bar") );
-        assertEquals("open.Bar", source.resolveType("open.Bar"));
-    }
-
-    public void testResolveFullyQualifiedTrumpsWildCard() throws Exception {
-        List<String> imports = new ArrayList<String>();
-        imports.add("bar.Bar");
-        imports.add("foo.Bar");
-        setImports( source, imports );
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("foo.*") );
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("bar.Bar") );
-        assertEquals("bar.Bar", source.resolveType("Bar"));
-    }
-
-    public void testResolveWildcard() throws Exception {
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("foo.Bar") );
-        setImports(source, Collections.singletonList("foo.*"));
-        assertEquals("foo.Bar", source.resolveType("Bar"));
-    }
-
-    public void testResolveJavaLangClass() throws Exception {
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("java.lang.System") );
-        assertEquals("java.lang.System", source.resolveType("System"));
-    }
-
-    public void testResolveSamePackageTrumpsWildcard() throws Exception {
-        List<String> imports = new ArrayList<String>();
-        imports.add("com.thoughtworks.qdox.model.Type");
-        imports.add("foo.*");
-        setImports( source, imports );
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("com.thoughtworks.qdox.model.Type") );
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("foo.Type") );
-        assertEquals("com.thoughtworks.qdox.model.Type", source.resolveType("Type"));
-    }
-
-    public void testResolveFullyQualifiedInnerClass() throws Exception {
-        setPackage(source, newJavaPackage("foo"));
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("foo.Bar$Fnord") );
-        assertEquals("foo.Bar$Fnord", source.resolveType("foo.Bar.Fnord"));
-    }
-
-    public void testResolvePartiallySpecifiedInnerClass() throws Exception {
-        setPackage(source, newJavaPackage("foo"));
-        setImports(source, Collections.singletonList("java.util.*"));
-        assertNotNull( source.getJavaClassLibrary().getJavaClass("foo.Bar$Fnord") );
-        assertEquals("foo.Bar$Fnord", source.resolveType("Bar.Fnord"));
-        assertEquals("java.util.Map$Entry", source.resolveType("Map.Entry"));
-    }
-    
 }
diff --git a/src/test/java/com/thoughtworks/qdox/model/JavaTypeTest.java b/src/test/java/com/thoughtworks/qdox/model/JavaTypeTest.java
index 937c884..cf59cdd 100644
--- a/src/test/java/com/thoughtworks/qdox/model/JavaTypeTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/JavaTypeTest.java
@@ -1,10 +1,14 @@
 package com.thoughtworks.qdox.model;
 
-import static org.junit.Assert.*;
-import static org.hamcrest.core.IsNot.*;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+
 import org.junit.Test;
 
-import com.thoughtworks.qdox.model.impl.DefaultJavaType;
+import com.thoughtworks.qdox.library.ClassLibrary;
+import com.thoughtworks.qdox.library.OrderedClassLibraryBuilder;
 
 public abstract class JavaTypeTest<T extends JavaType>
 {
@@ -13,6 +17,10 @@ public abstract class JavaTypeTest<T extends JavaType>
 
     public abstract T newType( String fullname, int dimensions );
 
+    public abstract T newType( String fullname, int dimensions, JavaClass clazz );
+    
+    public abstract JavaClass newJavaClass( ClassLibrary library );
+    
     @Test
     public void testToString()
         throws Exception
@@ -35,8 +43,9 @@ public abstract class JavaTypeTest<T extends JavaType>
     public void testEquals()
         throws Exception
     {
-        assertEquals( newType( "string" ), newType( "string" ) );
-        assertThat( newType( "string" ), not( newType( "int" ) ) );
+        JavaClass javaSource = newJavaClass( new OrderedClassLibraryBuilder().appendDefaultClassLoaders().getClassLibrary() );
+        assertEquals( newType( "long", 0, javaSource ), newType( "long", 0, javaSource ) );
+        assertThat( newType( "long", 0, javaSource ), not( newType( "int" ) ) );
         assertThat( newType( "long", 1 ), not( newType( "long" ) ) );
         assertThat( newType( "long" ), not( newType( "long", 2 ) ) );
         assertFalse( newType( "int" ).equals( null ) );
@@ -45,7 +54,7 @@ public abstract class JavaTypeTest<T extends JavaType>
     @Test
     public void testToStringVoid()
     {
-        assertEquals( "void", DefaultJavaType.VOID.toString() );
+        assertEquals( "void", newType("void").toString() );
     }
 
     @Test
diff --git a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaClassIT.java b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaClassIT.java
index b4bf9cf..d301775 100644
--- a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaClassIT.java
+++ b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaClassIT.java
@@ -63,7 +63,8 @@ public class DefaultJavaClassIT
         assertTrue( mapClass instanceof DefaultJavaClass );
         
         assertEquals( 1, mapClass.getNestedClasses().size() );
-        assertEquals( "java.util.Map$Entry",  mapClass.getNestedClassByName( "Entry" ).getFullyQualifiedName() );
+        assertEquals( "java.util.Map$Entry",  mapClass.getNestedClassByName( "Entry" ).getBinaryName() );
+        assertEquals( "java.util.Map.Entry",  mapClass.getNestedClassByName( "Entry" ).getFullyQualifiedName() );
         assertEquals( 1, Class.forName( "java.util.Map" ).getDeclaredClasses().length );
         assertEquals( "java.util.Map$Entry", Class.forName( "java.util.Map" ).getDeclaredClasses()[0].getName() );
     }
@@ -76,6 +77,8 @@ public class DefaultJavaClassIT
         assertNotNull( valueBean );
         assertEquals( "java.lang.Object", valueBean.getType().getFullyQualifiedName() );
         assertNotNull( valueBean.getAccessor() );
+        
+        assertEquals( "public abstract java.lang.Object java.util.Map$Entry.getValue()", Class.forName( "java.util.Map$Entry" ).getMethod("getValue").toString() );
         assertEquals( "public abstract java.lang.Object java.util.Map$Entry.getValue()", valueBean.getAccessor().toString() );
         assertNotNull( valueBean.getMutator() );
         assertEquals( "public abstract java.lang.Object java.util.Map$Entry.setValue(java.lang.Object)", valueBean.getMutator().toString() );
@@ -93,12 +96,11 @@ public class DefaultJavaClassIT
         JavaClass entryClass = library.getJavaClass( "java.util.Map$Entry" );
         assertTrue( entryClass instanceof DefaultJavaClass );
         
-        assertEquals( "java.util.Map$Entry", entryClass.getFullyQualifiedName() );
+        assertEquals( "java.util.Map$Entry", entryClass.getBinaryName() );
+        assertEquals( "java.util.Map.Entry", entryClass.getFullyQualifiedName() );
         assertEquals( "java.util.Map$Entry", Class.forName( "java.util.Map$Entry" ).getName() );
         assertEquals( "java.util.Map.Entry", entryClass.getCanonicalName() );
         assertEquals( "java.util.Map.Entry", Class.forName( "java.util.Map$Entry" ).getCanonicalName() );
         assertEquals( "Map.Entry", entryClass.getValue() );
-        
     }
-
 }
diff --git a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaClassTest.java b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaClassTest.java
index 2421f56..11a194b 100644
--- a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaClassTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaClassTest.java
@@ -54,7 +54,7 @@ public class DefaultJavaClassTest
     @Override
     public void setDeclaringClass( DefaultJavaClass clazz, JavaClass declaringClazz )
     {
-        clazz.setParentClass( declaringClazz );
+        clazz.setDeclaringClass( declaringClazz );
         
     }
 
diff --git a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaConstructorTest.java b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaConstructorTest.java
index 276b099..43a42b9 100644
--- a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaConstructorTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaConstructorTest.java
@@ -1,12 +1,10 @@
 package com.thoughtworks.qdox.model.impl;
 
-import static org.mockito.Mockito.*;
 import java.util.List;
 
 import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaConstructorTest;
 import com.thoughtworks.qdox.model.JavaParameter;
-import com.thoughtworks.qdox.model.impl.DefaultJavaConstructor;
 
 
 public class DefaultJavaConstructorTest extends JavaConstructorTest<DefaultJavaConstructor>
@@ -34,8 +32,8 @@ public class DefaultJavaConstructorTest extends JavaConstructorTest<DefaultJavaC
     }
     
     @Override
-    protected void setParentClass( DefaultJavaConstructor constructor, JavaClass parentClass )
+    protected void setDeclaringClass( DefaultJavaConstructor constructor, JavaClass parentClass )
     {
-        constructor.setParentClass( parentClass );
+        constructor.setDeclaringClass( parentClass );
     }
 }
diff --git a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaFieldTest.java b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaFieldTest.java
index c93cf23..6cc8bb5 100644
--- a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaFieldTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaFieldTest.java
@@ -20,8 +20,8 @@ public class DefaultJavaFieldTest
     {
         JavaSource source = new DefaultJavaSource( null );
         JavaClass javaClass = new DefaultJavaClass( source );
-        DefaultJavaField result = new DefaultJavaField();
-        result.setParentClass( javaClass );
+        DefaultJavaField result = new DefaultJavaField( "NAME" );
+        result.setDeclaringClass( javaClass );
         return result;
     }
 
@@ -64,6 +64,6 @@ public class DefaultJavaFieldTest
     @Override
     public void setDeclaringClass( DefaultJavaField fld, JavaClass cls )
     {
-        fld.setParentClass( cls );
+        fld.setDeclaringClass( cls );
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaMethodTest.java b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaMethodTest.java
index 84c5ed5..3eb7826 100644
--- a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaMethodTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaMethodTest.java
@@ -46,9 +46,9 @@ public class DefaultJavaMethodTest
         method.setReturns( type );
     }
 
-    public void setParentClass( DefaultJavaMethod method, JavaClass clazz )
+    public void setDeclaringClass( DefaultJavaMethod method, JavaClass clazz )
     {
-        method.setParentClass( clazz );
+        method.setDeclaringClass( clazz );
     }
 
     @Override
diff --git a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterTest.java b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterTest.java
index 71a9494..10889c5 100644
--- a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterTest.java
@@ -1,10 +1,8 @@
 package com.thoughtworks.qdox.model.impl;
 
 import com.thoughtworks.qdox.model.JavaClass;
-import com.thoughtworks.qdox.model.JavaConstructor;
-import com.thoughtworks.qdox.model.JavaMethod;
+import com.thoughtworks.qdox.model.JavaExecutable;
 import com.thoughtworks.qdox.model.JavaParameterTest;
-import com.thoughtworks.qdox.model.impl.DefaultJavaParameter;
 
 public class DefaultJavaParameterTest extends JavaParameterTest<DefaultJavaParameter>
 {
@@ -27,14 +25,8 @@ public class DefaultJavaParameterTest extends JavaParameterTest<DefaultJavaParam
     }
 
     @Override
-    protected void setMethod( DefaultJavaParameter parameter, JavaMethod method )
+    protected void setJavaExecutable( DefaultJavaParameter parameter, JavaExecutable executable )
     {
-        parameter.setDeclarator( method );
-    }
-    
-    @Override
-    protected void setConstructor( DefaultJavaParameter parameter, JavaConstructor constructor )
-    {
-        parameter.setDeclarator( constructor );        
+        parameter.setExecutable( executable );        
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterizedTypeTest.java b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterizedTypeTest.java
new file mode 100644
index 0000000..425dbd7
--- /dev/null
+++ b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultJavaParameterizedTypeTest.java
@@ -0,0 +1,154 @@
+package com.thoughtworks.qdox.model.impl;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.thoughtworks.qdox.library.ClassLoaderLibrary;
+import com.thoughtworks.qdox.model.JavaType;
+import com.thoughtworks.qdox.type.TypeResolver;
+
+public class DefaultJavaParameterizedTypeTest
+{
+    // Fields to verify if reflection acts the same
+    public List<String> listOfString;
+
+    public List<String>[] listOfStringArray;
+
+    public List<String>[][] listOfStringArrayArray;
+    
+    public Map.Entry<Integer, String> mapEntryIntegerForString;
+    
+    private TypeResolver typeResolver;
+    
+    @Before 
+    public void initMocks() {
+        ClassLoaderLibrary classLibrary = new ClassLoaderLibrary( null );
+        classLibrary.addDefaultLoader();
+        typeResolver = TypeResolver.byPackageName( null, classLibrary , null );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    @Test
+    public void testListOfString() throws Exception
+    {
+        DefaultJavaParameterizedType type = new DefaultJavaParameterizedType( "java.util.List", "List", 0, typeResolver );
+        DefaultJavaType genType = new DefaultJavaType( "java.lang.String", "String", 0, typeResolver );
+        type.setActualArgumentTypes( Collections.<JavaType>singletonList( genType ) );
+
+        Field field = DefaultJavaParameterizedTypeTest.class.getField( "listOfString" );
+
+        assertEquals( "List", type.getValue() );
+        assertEquals( "List<String>", type.getGenericValue() );
+
+        assertEquals( "java.util.List", type.getBinaryName() );
+        assertEquals( "java.util.List", type.getFullyQualifiedName() );
+
+        // Also compare with reflect implementations
+        assertThat( type.getSimpleName(), allOf( equalTo("List"),
+                                                 equalTo(field.getType().getSimpleName())));
+        assertThat( type.getCanonicalName(), allOf( equalTo("java.util.List"), 
+                                                    equalTo(field.getType().getCanonicalName())));
+        
+// Requires Java8        
+        assertThat( type.getGenericCanonicalName(), allOf( equalTo("java.util.List<java.lang.String>")/*, 
+                                                           equalTo(field.getGenericType().getTypeName())*/));
+    }
+
+    @SuppressWarnings( "unchecked" )
+    @Test
+    public void testListOfStringArray() throws Exception
+    {
+        DefaultJavaParameterizedType type = new DefaultJavaParameterizedType( "java.util.List", "List", 1, typeResolver );
+        DefaultJavaType genType = new DefaultJavaType( "java.lang.String", "String", 0, typeResolver );
+        type.setActualArgumentTypes( Collections.<JavaType>singletonList( genType ) );
+        
+        Field field = DefaultJavaParameterizedTypeTest.class.getField( "listOfStringArray" );
+
+        assertEquals( "List[]", type.getValue() );
+        assertEquals( "List<String>[]", type.getGenericValue() );
+
+        assertEquals( "java.util.List", type.getBinaryName() );
+        assertEquals( "java.util.List[]", type.getFullyQualifiedName() );
+
+        // Also compare with reflect implementations
+        assertThat( type.getSimpleName(), allOf( equalTo("List[]"),
+                                                 equalTo(field.getType().getSimpleName())));
+        assertThat( type.getCanonicalName(), allOf( equalTo("java.util.List[]"), 
+                                                    equalTo(field.getType().getCanonicalName())));
+        
+// requires java8        
+        assertThat( type.getGenericCanonicalName(), allOf( equalTo("java.util.List<java.lang.String>[]")/*, 
+                                                           equalTo(field.getGenericType().getTypeName())*/));
+        
+        assertThat( type.getComponentType().getSimpleName(), allOf( equalTo("List"), 
+                                                                    equalTo(field.getType().getComponentType().getSimpleName())));
+        assertThat( type.getComponentType().getCanonicalName(), allOf( equalTo("java.util.List"), 
+                                                                       equalTo(field.getType().getComponentType().getCanonicalName())));
+    }
+    
+    @SuppressWarnings( "unchecked" )
+    @Test
+    public void testListOfStringArrayArray() throws Exception
+    {
+        DefaultJavaParameterizedType type = new DefaultJavaParameterizedType( "java.util.List", "List", 2, typeResolver );
+        DefaultJavaType genType = new DefaultJavaType( "java.lang.String", "String", 0, typeResolver );
+        type.setActualArgumentTypes( Collections.<JavaType>singletonList( genType ) );
+        
+        Field field = DefaultJavaParameterizedTypeTest.class.getField( "listOfStringArrayArray" );
+
+        assertEquals( "List[][]", type.getValue() );
+        assertEquals( "List<String>[][]", type.getGenericValue() );
+
+        assertEquals( "java.util.List", type.getBinaryName() );
+        assertEquals( "java.util.List[][]", type.getFullyQualifiedName() );
+
+        // Also compare with reflect implementations
+        assertThat( type.getSimpleName(), allOf( equalTo("List[][]"),
+                                                 equalTo(field.getType().getSimpleName())));
+        assertThat( type.getCanonicalName(), allOf( equalTo("java.util.List[][]"), 
+                                                    equalTo(field.getType().getCanonicalName())));
+        
+        
+//        assertThat( type.getComponentType().getSimpleName(), allOf( equalTo("java.util.List"), 
+//                                                                    equalTo(field.getType().getComponentType().getSimpleName())));
+    }
+    
+    @SuppressWarnings( "unchecked" )
+    @Test
+    public void testMapEntryIntegerForString() throws Exception
+    {
+        DefaultJavaParameterizedType type = new DefaultJavaParameterizedType( "java.util.Map$Entry", "Map.Entry", 0, typeResolver );
+        DefaultJavaType keyType = new DefaultJavaType( "java.lang.Integer", "Integer", 0, typeResolver );
+        DefaultJavaType valueType = new DefaultJavaType( "java.lang.String", "String", 0, typeResolver );
+        type.setActualArgumentTypes( Arrays.<JavaType>asList( keyType, valueType ) );
+        
+        Field field = DefaultJavaParameterizedTypeTest.class.getField( "mapEntryIntegerForString" );
+
+        assertEquals( "Map.Entry", type.getValue() );
+        assertEquals( "Map.Entry<Integer,String>", type.getGenericValue() );
+
+        assertEquals( "java.util.Map$Entry", type.getBinaryName() );
+        assertEquals( "java.util.Map.Entry", type.getFullyQualifiedName() );
+
+        // Also compare with reflect implementations
+        assertThat( type.getSimpleName(), allOf( equalTo("Entry"),
+                                                 equalTo(field.getType().getSimpleName())));
+        assertThat( type.getCanonicalName(), allOf( equalTo("java.util.Map.Entry"), 
+                                                    equalTo(field.getType().getCanonicalName())));
+        // this is buggy for multiple JDKs 
+        assertThat( type.getGenericCanonicalName(), allOf( equalTo("java.util.Map.Entry<java.lang.Integer,java.lang.String>") /*, 
+                                                           equalTo(field.getGenericType().getTypeName())*/ ));
+    }
+
+}
diff --git a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultTypeTest.java b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultTypeTest.java
index 544f2c6..d0984b0 100644
--- a/src/test/java/com/thoughtworks/qdox/model/impl/DefaultTypeTest.java
+++ b/src/test/java/com/thoughtworks/qdox/model/impl/DefaultTypeTest.java
@@ -3,24 +3,20 @@ package com.thoughtworks.qdox.model.impl;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.Collections;
 
 import org.junit.Test;
 
 import com.thoughtworks.qdox.library.ClassLibrary;
-import com.thoughtworks.qdox.model.JavaSource;
+import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaTypeTest;
 
 public class DefaultTypeTest
     extends JavaTypeTest<DefaultJavaType>
 {
 
-    public JavaSource newJavaSource( ClassLibrary library )
+    public JavaClass newJavaClass( ClassLibrary library )
     {
-        return new DefaultJavaSource( library );
+        return new DefaultJavaClass(new DefaultJavaSource( library ));
     }
 
     public DefaultJavaType newType( String fullname )
@@ -33,9 +29,9 @@ public class DefaultTypeTest
         return new DefaultJavaType( fullname, dimensions );
     }
 
-    public DefaultJavaType newType( String fullname, int dimensions, JavaSource source )
+    public DefaultJavaType newType( String fullname, int dimensions, JavaClass clazz )
     {
-        return new DefaultJavaType( fullname, dimensions, source );
+        return new DefaultJavaType( fullname, dimensions );
     }
 
     @Test
@@ -54,19 +50,4 @@ public class DefaultTypeTest
         assertEquals( "int", newType( "int", 1 ).getComponentType().getFullyQualifiedName() );
         assertEquals( "long", newType( "long", 3 ).getComponentType().getFullyQualifiedName() );
     }
-
-    @Test
-    public void testResolving()
-        throws Exception
-    {
-        JavaSource src = mock( JavaSource.class );
-        when( src.getImports() ).thenReturn( Collections.singletonList( "foo.*" ) );
-        DefaultJavaType type = DefaultJavaType.createUnresolved( "Bar", 0, src );
-        assertEquals( false, type.isResolved() );
-
-        when( src.resolveType( "Bar" ) ).thenReturn( "foo.Bar" );
-        assertEquals( true, type.isResolved() );
-        assertEquals( "Bar", type.getValue() );
-        assertEquals( "foo.Bar", type.getFullyQualifiedName() );
-    }
 }
\ No newline at end of file
diff --git a/src/test/java/com/thoughtworks/qdox/parser/LexerTest.java b/src/test/java/com/thoughtworks/qdox/parser/LexerTest.java
index c69f75b..1cdb840 100644
--- a/src/test/java/com/thoughtworks/qdox/parser/LexerTest.java
+++ b/src/test/java/com/thoughtworks/qdox/parser/LexerTest.java
@@ -639,4 +639,209 @@ public class LexerTest extends TestCase {
         assertLex( Parser.PARENCLOSE, lexer );
         assertLex( 0, lexer );
     }
+    
+    public void testModule()
+        throws Exception
+    {
+        String in = "@Foo(1) @Foo(2) @Bar\n" + 
+            "open module M.N {\n" + 
+            "  requires A.B;\n" + 
+            "  requires transitive C.D;\n" + 
+            "  requires static E.F;\n" + 
+            "  requires transitive static G.H;\n" + 
+            "  exports P.Q;\n" + 
+            "  exports R.S to T1.U1, T2.U2;\n" + 
+            "  opens P.Q;\n" + 
+            "  opens R.S to T1.U1, T2.U2;\n" + 
+            "  uses V.W;\n" + 
+            "  provides X.Y with Z1.Z2, Z3.Z4;\n" + 
+            "}";
+        Lexer lexer = new JFlexLexer( new StringReader( in ) );
+        assertLex( Parser.AT, lexer );
+        assertLex( Parser.IDENTIFIER, "Foo", lexer );
+        assertLex( Parser.PARENOPEN, lexer );
+        assertLex( Parser.INTEGER_LITERAL, "1", lexer );
+        assertLex( Parser.PARENCLOSE, lexer );
+        assertLex( Parser.AT, lexer );
+        assertLex( Parser.IDENTIFIER, "Foo", lexer );
+        assertLex( Parser.PARENOPEN, lexer );
+        assertLex( Parser.INTEGER_LITERAL, "2", lexer );
+        assertLex( Parser.PARENCLOSE, lexer );
+        assertLex( Parser.AT, lexer );
+        assertLex( Parser.IDENTIFIER, "Bar", lexer );
+        
+        assertLex( Parser.OPEN, lexer );
+        assertLex( Parser.MODULE, lexer );
+        assertLex( Parser.IDENTIFIER, "M", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "N", lexer );
+        assertLex( Parser.BRACEOPEN, lexer );
+        
+        assertLex( Parser.REQUIRES, lexer );
+        assertLex( Parser.IDENTIFIER, "A", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "B", lexer );
+        assertLex( Parser.SEMI, lexer );
+        
+        assertLex( Parser.REQUIRES, lexer );
+        assertLex( Parser.TRANSITIVE, lexer );
+        assertLex( Parser.IDENTIFIER, "C", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "D", lexer );
+        assertLex( Parser.SEMI, lexer );
+        
+        assertLex( Parser.REQUIRES, lexer );
+        assertLex( Parser.STATIC, lexer );
+        assertLex( Parser.IDENTIFIER, "E", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "F", lexer );
+        assertLex( Parser.SEMI, lexer );
+        
+        assertLex( Parser.REQUIRES, lexer );
+        assertLex( Parser.TRANSITIVE, lexer );
+        assertLex( Parser.STATIC, lexer );
+        assertLex( Parser.IDENTIFIER, "G", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "H", lexer );
+        assertLex( Parser.SEMI, lexer );
+
+        assertLex( Parser.EXPORTS, lexer );
+        assertLex( Parser.IDENTIFIER, "P", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "Q", lexer );
+        assertLex( Parser.SEMI, lexer );
+
+        assertLex( Parser.EXPORTS, lexer );
+        assertLex( Parser.IDENTIFIER, "R", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "S", lexer );
+        assertLex( Parser.TO, lexer );
+        assertLex( Parser.IDENTIFIER, "T1", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "U1", lexer );
+        assertLex( Parser.COMMA, lexer );
+        assertLex( Parser.IDENTIFIER, "T2", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "U2", lexer );
+        assertLex( Parser.SEMI, lexer );
+
+        assertLex( Parser.OPENS, lexer );
+        assertLex( Parser.IDENTIFIER, "P", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "Q", lexer );
+        assertLex( Parser.SEMI, lexer );
+
+        assertLex( Parser.OPENS, lexer );
+        assertLex( Parser.IDENTIFIER, "R", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "S", lexer );
+        assertLex( Parser.TO, lexer );
+        assertLex( Parser.IDENTIFIER, "T1", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "U1", lexer );
+        assertLex( Parser.COMMA, lexer );
+        assertLex( Parser.IDENTIFIER, "T2", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "U2", lexer );
+        assertLex( Parser.SEMI, lexer );
+
+        assertLex( Parser.USES, lexer );
+        assertLex( Parser.IDENTIFIER, "V", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "W", lexer );
+        assertLex( Parser.SEMI, lexer );
+
+        assertLex( Parser.PROVIDES, lexer );
+        assertLex( Parser.IDENTIFIER, "X", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "Y", lexer );
+        assertLex( Parser.WITH, lexer );
+        assertLex( Parser.IDENTIFIER, "Z1", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "Z2", lexer );
+        assertLex( Parser.COMMA, lexer );
+        assertLex( Parser.IDENTIFIER, "Z3", lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "Z4", lexer );
+        assertLex( Parser.SEMI, lexer );
+
+        assertLex( Parser.BRACECLOSE, lexer );
+        assertLex( 0, lexer );
+    }
+    
+    public void testModuleAsIdentifier() throws Exception
+    {
+        String in = ""
+            + "package module.module;\n"
+            + "import static module;\n"
+            + "import module.module;\n"
+            + "@module @module.module @module(module=module)\n"
+            + "public class module extends module implements module,module {\n"
+            + "  @module\n"
+            + "  private module module;\n"
+            + "  protected module module(module module) {}\n"
+            + "}";
+        Lexer lexer = new JFlexLexer( new StringReader( in ) );
+        assertLex( Parser.PACKAGE, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "module", lexer );
+        assertLex( Parser.SEMI, lexer );
+
+        assertLex( Parser.IMPORT, lexer );
+        assertLex( Parser.STATIC, lexer );
+        assertLex( Parser.IDENTIFIER, "module", lexer );
+        assertLex( Parser.SEMI, lexer );
+        
+        assertLex( Parser.IMPORT, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "module", lexer );
+        assertLex( Parser.SEMI, lexer );
+        
+        assertLex( Parser.AT, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.AT, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.DOT, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.AT, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.PARENOPEN, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.EQUALS, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.PARENCLOSE, lexer );
+
+        assertLex( Parser.PUBLIC, lexer );
+        assertLex( Parser.CLASS, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.EXTENDS, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.IMPLEMENTS, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.COMMA, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.BRACEOPEN, lexer );
+
+        assertLex( Parser.AT, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+
+        assertLex( Parser.PRIVATE, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.IDENTIFIER, "module", lexer );
+        assertLex( Parser.SEMI, lexer );
+
+        assertLex( Parser.PROTECTED, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.IDENTIFIER, "module", lexer );
+        assertLex( Parser.PARENOPEN, lexer );
+        assertLex( Parser.IDENTIFIER, "module",  lexer );
+        assertLex( Parser.IDENTIFIER, "module", lexer );
+        assertLex( Parser.PARENCLOSE, lexer );
+        assertLex( Parser.CODEBLOCK, lexer );
+
+        assertLex( Parser.BRACECLOSE, lexer );
+        assertLex( 0, lexer );
+    }
 }
diff --git a/src/test/java/com/thoughtworks/qdox/parser/ParserTest.java b/src/test/java/com/thoughtworks/qdox/parser/ParserTest.java
index 19f9409..e8716db 100644
--- a/src/test/java/com/thoughtworks/qdox/parser/ParserTest.java
+++ b/src/test/java/com/thoughtworks/qdox/parser/ParserTest.java
@@ -9,23 +9,25 @@ import static org.mockito.Mockito.when;
 import java.util.Collection;
 import java.util.LinkedList;
 
-import junit.framework.TestCase;
-
 import org.junit.Assert;
 import org.mockito.ArgumentCaptor;
 import org.mockito.stubbing.answers.ReturnsElementsOf;
 
 import com.thoughtworks.qdox.builder.Builder;
+import com.thoughtworks.qdox.parser.expression.ExpressionDef;
 import com.thoughtworks.qdox.parser.impl.Parser;
 import com.thoughtworks.qdox.parser.structs.AnnoDef;
 import com.thoughtworks.qdox.parser.structs.ClassDef;
 import com.thoughtworks.qdox.parser.structs.FieldDef;
 import com.thoughtworks.qdox.parser.structs.InitDef;
 import com.thoughtworks.qdox.parser.structs.MethodDef;
+import com.thoughtworks.qdox.parser.structs.ModuleDef;
 import com.thoughtworks.qdox.parser.structs.PackageDef;
 import com.thoughtworks.qdox.parser.structs.TypeDef;
 import com.thoughtworks.qdox.parser.structs.WildcardTypeDef;
 
+import junit.framework.TestCase;
+
 public class ParserTest extends TestCase {
     
 	private Collection<Integer> lexValues = new LinkedList<Integer>();
@@ -94,6 +96,29 @@ public class ParserTest extends TestCase {
         verify(builder).addPackage( argument.capture() );
         assertEquals( "com.blah.thingy.x", argument.getValue().getName() );
     }
+    
+    public void testPackageWithAnnotation() throws Exception {
+
+        // setup values
+        setupLex(Parser.AT);
+        setupLex(Parser.IDENTIFIER, "Bar");
+        setupLex(Parser.PACKAGE);
+        setupLex(Parser.IDENTIFIER, "mypackage");
+        setupLex(Parser.SEMI);
+        setupLex(0);
+
+        // execute
+        Parser parser = new Parser(lexer, builder);
+        parser.parse();
+
+        // verify
+        ArgumentCaptor<AnnoDef> annoCaptor = ArgumentCaptor.forClass( AnnoDef.class );
+        verify( builder ).addAnnotation( annoCaptor.capture() );
+        assertEquals( "Bar", annoCaptor.getValue().getTypeDef().getName() );
+        ArgumentCaptor<PackageDef> argument = ArgumentCaptor.forClass( PackageDef.class );
+        verify( builder ).addPackage( argument.capture() );
+        assertEquals( "mypackage", argument.getValue().getName() );
+    }
 
     public void testImportWithOneWord() throws Exception {
 
@@ -687,102 +712,6 @@ public class ParserTest extends TestCase {
         assertEquals( ClassDef.CLASS, cls2.getType() );
     }
 
-/*can't be tested like this anymore*/    
-//    public void testJavaDocAppearingAllOverThePlace() throws Exception {
-//
-//        // setup values
-//        setupLex(Parser.JAVADOCSTART);
-//        setupLex(Parser.JAVADOCLINE, "javadoc1");
-//        setupLex(Parser.JAVADOCEND);
-//
-//        setupLex(Parser.JAVADOCSTART);
-//        setupLex(Parser.JAVADOCLINE, "javadoc2");
-//        setupLex(Parser.JAVADOCEND);
-//
-//        setupLex(Parser.PACKAGE);
-//        setupLex(Parser.IDENTIFIER, "mypackage");
-//        setupLex(Parser.SEMI);
-//
-//        setupLex(Parser.JAVADOCSTART);
-//        setupLex(Parser.JAVADOCLINE, "javadoc3");
-//        setupLex(Parser.JAVADOCEND);
-//
-//        setupLex(Parser.JAVADOCSTART);
-//        setupLex(Parser.JAVADOCLINE, "javadoc4");
-//        setupLex(Parser.JAVADOCEND);
-//
-//        setupLex(Parser.IMPORT);
-//        setupLex(Parser.IDENTIFIER, "anotherpackage");
-//        setupLex(Parser.DOT);
-//        setupLex(Parser.IDENTIFIER, "Something");
-//        setupLex(Parser.SEMI);
-//
-//        setupLex(Parser.JAVADOCSTART);
-//        setupLex(Parser.JAVADOCLINE, "javadoc5");
-//        setupLex(Parser.JAVADOCEND);
-//
-//        setupLex(Parser.JAVADOCSTART);
-//        setupLex(Parser.JAVADOCLINE, "javadoc6");
-//        setupLex(Parser.JAVADOCEND);
-//
-//        setupLex(Parser.IMPORT);
-//        setupLex(Parser.IDENTIFIER, "elsewhere");
-//        setupLex(Parser.DOT);
-//        setupLex(Parser.STAR);
-//        setupLex(Parser.SEMI);
-//
-//        setupLex(Parser.JAVADOCSTART);
-//        setupLex(Parser.JAVADOCLINE, "javadoc7");
-//        setupLex(Parser.JAVADOCEND);
-//
-//        setupLex(Parser.JAVADOCSTART);
-//        setupLex(Parser.JAVADOCLINE, "javadoc8");
-//        setupLex(Parser.JAVADOCEND);
-//
-//        setupLex(Parser.PUBLIC);
-//        setupLex(Parser.CLASS);
-//        setupLex(Parser.IDENTIFIER, "MyClass");
-//        setupLex(Parser.BRACEOPEN);
-//        setupLex(Parser.BRACECLOSE);
-//
-//        setupLex(Parser.JAVADOCSTART);
-//        setupLex(Parser.JAVADOCLINE, "javadoc9");
-//        setupLex(Parser.JAVADOCEND);
-//
-//        setupLex(Parser.JAVADOCSTART);
-//        setupLex(Parser.JAVADOCLINE, "javadoc10");
-//        setupLex(Parser.JAVADOCEND);
-//
-//        setupLex(0);
-//
-//        // execute
-//        Parser parser = new Parser(lexer, builder);
-//        parser.parse();
-//
-//        // expectations
-//        ClassDef cls = new ClassDef();
-//        cls.name = "MyClass";
-//        cls.modifiers.add("public");
-//        
-//        // verify
-//        verify(builder).addJavaDoc("javadoc1");
-//        verify(builder).addJavaDoc("javadoc2");
-//        verify(builder).addPackage( new PackageDef( "mypackage" ) );
-//        verify(builder).addJavaDoc("javadoc3");
-//        verify(builder).addJavaDoc("javadoc4");
-//        verify(builder).addImport( "anotherpackage.Something" );
-//        verify(builder).addJavaDoc("javadoc5");
-//        verify(builder).addJavaDoc("javadoc6");
-//        verify(builder).addImport("elsewhere.*");
-//        verify(builder).addJavaDoc("javadoc7");
-//        verify(builder).beginClass( cls );
-//        verify(builder).endClass();
-//        verify(builder).addJavaDoc("javadoc8");
-//        verify(builder).addJavaDoc("javadoc9");
-//        verify(builder).addJavaDoc("javadoc10");
-//
-//    }
-
     public void testSimpleVoidMethod() throws Exception {
 
         // setup values
@@ -1238,6 +1167,52 @@ public class ParserTest extends TestCase {
         Assert.assertArrayEquals( new String[] { "final", "volatile" }, parameterCaptor.getValue().getModifiers().toArray( new String[0] ) );
         assertEquals( new TypeDef("int"), parameterCaptor.getValue().getType() );
     }
+    
+    public void testMethodWithAnnotatedGenericReturnValue() throws Exception {
+    	
+        setupLex(Parser.CLASS);
+        setupLex(Parser.IDENTIFIER, "MyClass");
+        setupLex(Parser.BRACEOPEN);
+        
+        setupLex(Parser.PUBLIC);
+        setupLex(Parser.LESSTHAN);
+        setupLex(Parser.IDENTIFIER, "T");
+        setupLex(Parser.GREATERTHAN);
+        setupLex(Parser.AT);
+        setupLex(Parser.IDENTIFIER, "Nullable");
+        setupLex(Parser.IDENTIFIER, "T");
+        setupLex(Parser.IDENTIFIER, "doSomething");
+        setupLex(Parser.PARENOPEN);
+        setupLex(Parser.PARENCLOSE);
+        setupLex(Parser.CODEBLOCK);
+
+        setupLex(Parser.BRACECLOSE);
+        setupLex(0);
+        
+    	Parser parser = new Parser(lexer, builder);
+    	parser.parse();
+        
+        ArgumentCaptor<ClassDef> classCaptor = ArgumentCaptor.forClass(ClassDef.class);
+        ArgumentCaptor<MethodDef> methodCaptor = ArgumentCaptor.forClass(MethodDef.class);
+        ArgumentCaptor<AnnoDef> annotationCaptor = ArgumentCaptor.forClass(AnnoDef.class);
+
+        verify(builder).beginClass(classCaptor.capture());
+        verify(builder).beginMethod();
+        verify(builder).endMethod(methodCaptor.capture());
+        verify(builder).addAnnotation(annotationCaptor.capture());
+        verify(builder).endClass();
+
+        ClassDef cls = classCaptor.getValue();
+        assertEquals("MyClass", cls.getName());
+
+        MethodDef mth = methodCaptor.getValue();
+        assertTrue(mth.getModifiers().contains("public"));
+        assertEquals(new TypeDef("T"), mth.getReturnType());
+        assertEquals("doSomething", mth.getName());
+        
+        AnnoDef annotation = annotationCaptor.getValue();
+        assertEquals("Nullable", annotation.getTypeDef().getName());
+    }
 
     public void testMethodThrowingOneException() throws Exception {
 
@@ -2828,6 +2803,224 @@ public class ParserTest extends TestCase {
         assertFalse( init.isStatic() );
         assertEquals( "//test", init.getBlockContent() );
     }
+    
+    public void testModule() throws Exception
+    {
+        setupLex( Parser.AT );
+        setupLex( Parser.IDENTIFIER, "Foo" );
+        setupLex( Parser.PARENOPEN );
+        setupLex( Parser.INTEGER_LITERAL, "1" );
+        setupLex( Parser.PARENCLOSE );
+        setupLex( Parser.AT );
+        setupLex( Parser.IDENTIFIER, "Foo" );
+        setupLex( Parser.PARENOPEN );
+        setupLex( Parser.INTEGER_LITERAL, "2" );
+        setupLex( Parser.PARENCLOSE );
+        setupLex( Parser.AT );
+        setupLex( Parser.IDENTIFIER, "Bar" );
+        
+        setupLex( Parser.OPEN );
+        setupLex( Parser.MODULE );
+        setupLex( Parser.IDENTIFIER, "M" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "N" );
+        setupLex( Parser.BRACEOPEN );
+        
+        setupLex( Parser.REQUIRES );
+        setupLex( Parser.IDENTIFIER, "A" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "B" );
+        setupLex( Parser.SEMI );
+        
+        setupLex( Parser.REQUIRES );
+        setupLex( Parser.TRANSITIVE );
+        setupLex( Parser.IDENTIFIER, "C" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "D" );
+        setupLex( Parser.SEMI );
+        
+        setupLex( Parser.REQUIRES );
+        setupLex( Parser.STATIC );
+        setupLex( Parser.IDENTIFIER, "E" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "F" );
+        setupLex( Parser.SEMI );
+        
+        setupLex( Parser.REQUIRES );
+        setupLex( Parser.TRANSITIVE );
+        setupLex( Parser.STATIC );
+        setupLex( Parser.IDENTIFIER, "G" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "H" );
+        setupLex( Parser.SEMI );
+
+        setupLex( Parser.EXPORTS );
+        setupLex( Parser.IDENTIFIER, "P" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "Q" );
+        setupLex( Parser.SEMI );
+
+        setupLex( Parser.EXPORTS );
+        setupLex( Parser.IDENTIFIER, "R" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "S" );
+        setupLex( Parser.TO );
+        setupLex( Parser.IDENTIFIER, "T1" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "U1" );
+        setupLex( Parser.COMMA );
+        setupLex( Parser.IDENTIFIER, "T2" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "U2" );
+        setupLex( Parser.SEMI );
+
+        setupLex( Parser.OPENS );
+        setupLex( Parser.IDENTIFIER, "P" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "Q" );
+        setupLex( Parser.SEMI );
+
+        setupLex( Parser.OPENS );
+        setupLex( Parser.IDENTIFIER, "R" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "S" );
+        setupLex( Parser.TO );
+        setupLex( Parser.IDENTIFIER, "T1" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "U1" );
+        setupLex( Parser.COMMA );
+        setupLex( Parser.IDENTIFIER, "T2" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "U2" );
+        setupLex( Parser.SEMI );
+
+        setupLex( Parser.USES );
+        setupLex( Parser.IDENTIFIER, "V" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "W" );
+        setupLex( Parser.SEMI );
+
+        setupLex( Parser.PROVIDES );
+        setupLex( Parser.IDENTIFIER, "X" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "Y" );
+        setupLex( Parser.WITH );
+        setupLex( Parser.IDENTIFIER, "Z1" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "Z2" );
+        setupLex( Parser.COMMA );
+        setupLex( Parser.IDENTIFIER, "Z3" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "Z4" );
+        setupLex( Parser.SEMI );
+
+        setupLex( Parser.BRACECLOSE );
+        setupLex( 0 );
+        
+       // execute
+        Parser parser = new Parser( lexer, builder );
+        parser.parse();
+
+        ArgumentCaptor<AnnoDef> annoCaptor = ArgumentCaptor.forClass( AnnoDef.class );
+        verify( builder, times(3) ).addAnnotation( annoCaptor.capture() );
+        assertEquals( "Foo", annoCaptor.getAllValues().get( 0 ).getTypeDef().getName() );
+        assertEquals( "1", annoCaptor.getAllValues().get( 0 ).getArgs().get( "value" ).toString());
+        assertEquals( "Foo", annoCaptor.getAllValues().get( 1 ).getTypeDef().getName() );
+        assertEquals( "2", annoCaptor.getAllValues().get( 1 ).getArgs().get( "value" ).toString());
+        assertEquals( "Bar", annoCaptor.getAllValues().get( 2 ).getTypeDef().getName() );
+        assertEquals( null, annoCaptor.getAllValues().get( 2 ).getArgs().get( "value" ));
+        
+        ArgumentCaptor<ModuleDef> moduleCaptor = ArgumentCaptor.forClass( ModuleDef.class );
+        verify( builder ).setModule( moduleCaptor.capture() );
+        assertEquals( "M.N", moduleCaptor.getValue().getName() );
+        assertEquals( true, moduleCaptor.getValue().isOpen() );
+        
+        ArgumentCaptor<ModuleDef.RequiresDef> requiresCaptor = ArgumentCaptor.forClass( ModuleDef.RequiresDef.class );
+        verify( builder, times(4) ).addRequires( requiresCaptor.capture() );
+        assertEquals( "A.B", requiresCaptor.getAllValues().get(0).getName() );
+        assertEquals( false, requiresCaptor.getAllValues().get(0).getModifiers().contains( "transitive" ) );
+        assertEquals( false, requiresCaptor.getAllValues().get(0).getModifiers().contains( "static" ) );
+        
+        assertEquals( "C.D", requiresCaptor.getAllValues().get(1).getName() );
+        assertEquals( true, requiresCaptor.getAllValues().get(1).getModifiers().contains( "transitive" ) );
+        assertEquals( false, requiresCaptor.getAllValues().get(1).getModifiers().contains( "static" ) );
+        
+        assertEquals( "E.F", requiresCaptor.getAllValues().get(2).getName() );
+        assertEquals( false, requiresCaptor.getAllValues().get(2).getModifiers().contains( "transitive" ) );
+        assertEquals( true, requiresCaptor.getAllValues().get(2).getModifiers().contains( "static" ) );
+        
+        assertEquals( "G.H", requiresCaptor.getAllValues().get(3).getName() );
+        assertEquals( true, requiresCaptor.getAllValues().get(3).getModifiers().contains( "transitive" ) );
+        assertEquals( true, requiresCaptor.getAllValues().get(3).getModifiers().contains( "static" ) );
+        
+        ArgumentCaptor<ModuleDef.ExportsDef> exportsCaptor = ArgumentCaptor.forClass( ModuleDef.ExportsDef.class );
+        verify( builder, times(2) ).addExports( exportsCaptor.capture() );
+        assertEquals( "P.Q", exportsCaptor.getAllValues().get( 0 ).getSource() );
+        assertEquals( 0, exportsCaptor.getAllValues().get( 0 ).getTargets().size() );
+
+        assertEquals( "R.S", exportsCaptor.getAllValues().get( 1 ).getSource() );
+        assertEquals( 2, exportsCaptor.getAllValues().get( 1 ).getTargets().size() );
+        assertEquals( true, exportsCaptor.getAllValues().get( 1 ).getTargets().contains( "T1.U1" ));
+        assertEquals( true, exportsCaptor.getAllValues().get( 1 ).getTargets().contains( "T2.U2" ));
+        
+        ArgumentCaptor<ModuleDef.OpensDef> opensCaptor = ArgumentCaptor.forClass( ModuleDef.OpensDef.class );
+        verify( builder, times(2) ).addOpens( opensCaptor.capture() );
+        assertEquals( "P.Q", opensCaptor.getAllValues().get( 0 ).getSource() );
+        assertEquals( 0, opensCaptor.getAllValues().get( 0 ).getTargets().size() );
+
+        assertEquals( "R.S", opensCaptor.getAllValues().get( 1 ).getSource() );
+        assertEquals( 2, opensCaptor.getAllValues().get( 1 ).getTargets().size() );
+        assertEquals( true, opensCaptor.getAllValues().get( 1 ).getTargets().contains( "T1.U1" ));
+        assertEquals( true, opensCaptor.getAllValues().get( 1 ).getTargets().contains( "T2.U2" ));
+        
+        ArgumentCaptor<ModuleDef.UsesDef> usesCaptor = ArgumentCaptor.forClass( ModuleDef.UsesDef.class );
+        verify( builder ).addUses( usesCaptor.capture() );
+        assertEquals( "V.W", usesCaptor.getValue().getService().getName() );
+        
+        ArgumentCaptor<ModuleDef.ProvidesDef> providesCaptor = ArgumentCaptor.forClass( ModuleDef.ProvidesDef.class );
+        verify( builder, times(1) ).addProvides( providesCaptor.capture() );
+        assertEquals( "X.Y", providesCaptor.getAllValues().get(0).getService().getName() );
+        assertEquals( "Z1.Z2", providesCaptor.getAllValues().get(0).getImplementations().get(0).getName() );
+        assertEquals( "Z3.Z4", providesCaptor.getAllValues().get(0).getImplementations().get(1).getName() );
+    }
+    
+    public void testCEnums() throws Exception {
+        setupLex( Parser.PUBLIC );
+        setupLex( Parser.ENUM );
+        setupLex( Parser.IDENTIFIER, "EnumWithFields" );
+        setupLex( Parser.BRACEOPEN );
+        
+        setupLex( Parser.IDENTIFIER, "VALUEA" );
+        setupLex( Parser.PARENOPEN );
+        setupLex( Parser.IDENTIFIER, "By" );
+        setupLex( Parser.DOT );
+        setupLex( Parser.IDENTIFIER, "linkText" );
+        setupLex( Parser.PARENOPEN );
+        setupLex( Parser.STRING_LITERAL, "\"G\"");
+        setupLex( Parser.PARENCLOSE );
+        setupLex( Parser.COMMA );
+        setupLex( Parser.STRING_LITERAL, "\"H\"");
+        setupLex( Parser.PARENCLOSE );
+        
+        setupLex( Parser.BRACECLOSE );
+        setupLex( 0 );        
+        
+        // execute
+        Parser parser = new Parser( lexer, builder );
+        parser.parse();
+        
+        // expectations
+        ArgumentCaptor<ClassDef> classCaptor = ArgumentCaptor.forClass( ClassDef.class );
+        ArgumentCaptor<FieldDef> fieldCaptor = ArgumentCaptor.forClass( FieldDef.class );
+        ArgumentCaptor<ExpressionDef> argumentCaptor = ArgumentCaptor.forClass( ExpressionDef.class );
+
+        // verify
+        verify( builder ).beginClass( classCaptor.capture() );
+        verify( builder ).beginField( fieldCaptor.capture() ); 
+        verify( builder, times(3) ).addArgument( argumentCaptor.capture() );
+        verify( builder ).endField();
+        verify( builder ).endClass();
+    }
 
     private void setupLex(int token, String value) {
         lexValues.add( token );
diff --git a/src/test/java/com/thoughtworks/qdox/parser/impl/DefaultJavaCommentLexerTest.java b/src/test/java/com/thoughtworks/qdox/parser/impl/DefaultJavaCommentLexerTest.java
index 01a13e5..7288534 100644
--- a/src/test/java/com/thoughtworks/qdox/parser/impl/DefaultJavaCommentLexerTest.java
+++ b/src/test/java/com/thoughtworks/qdox/parser/impl/DefaultJavaCommentLexerTest.java
@@ -26,6 +26,22 @@ public class DefaultJavaCommentLexerTest
     }
 
     @Test
+    public void testCompactMultiLineComment2() throws Exception {
+        lexer = new DefaultJavaCommentLexer( new StringReader("/***/"));
+        lexAssert(DefaultJavaCommentParser.JAVADOCSTART, "/**");
+        lexAssert(DefaultJavaCommentParser.JAVADOCEND, "*/");
+        lexAssert( 0 );
+    }
+
+    @Test
+    public void testCompactMultiLineComment3() throws Exception {
+        lexer = new DefaultJavaCommentLexer( new StringReader("/*****/"));
+        lexAssert(DefaultJavaCommentParser.JAVADOCSTART, "/****");
+        lexAssert(DefaultJavaCommentParser.JAVADOCEND, "*/");
+        lexAssert( 0 );
+    }
+
+    @Test
     public void testSingleRowMultiLineComment() throws Exception {
         lexer = new DefaultJavaCommentLexer( new StringReader("/* multiline comment with one row */"));
         lexAssert( 0 );
diff --git a/src/test/java/com/thoughtworks/qdox/traversal/TraversalTest.java b/src/test/java/com/thoughtworks/qdox/traversal/TraversalTest.java
index 9f4d351..079a8d0 100644
--- a/src/test/java/com/thoughtworks/qdox/traversal/TraversalTest.java
+++ b/src/test/java/com/thoughtworks/qdox/traversal/TraversalTest.java
@@ -4,7 +4,7 @@ import junit.framework.TestCase;
 
 import com.thoughtworks.qdox.JavaProjectBuilder;
 import com.thoughtworks.qdox.model.JavaClass;
-import com.thoughtworks.qdox.model.impl.AbstractBaseMethod;
+import com.thoughtworks.qdox.model.impl.DefaultJavaExecutable;
 import com.thoughtworks.qdox.model.impl.DefaultJavaMethod;
 
 public class TraversalTest extends TestCase {
@@ -25,7 +25,7 @@ public class TraversalTest extends TestCase {
         JavaClass parentClass = javaClass.getSuperJavaClass();
         assertNotNull("Parent class not found", parentClass);
         assertEquals("Parent class traversal has returned the wrong parent",
-                AbstractBaseMethod.class.getName(),
+                DefaultJavaExecutable.class.getName(),
                 parentClass.getFullyQualifiedName());
 
     }
diff --git a/src/test/java/com/thoughtworks/qdox/type/TypeResolverTest.java b/src/test/java/com/thoughtworks/qdox/type/TypeResolverTest.java
new file mode 100644
index 0000000..ad2a9c9
--- /dev/null
+++ b/src/test/java/com/thoughtworks/qdox/type/TypeResolverTest.java
@@ -0,0 +1,167 @@
+package com.thoughtworks.qdox.type;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import com.thoughtworks.qdox.library.ClassLibrary;
+import com.thoughtworks.qdox.type.TypeResolver;
+
+public class TypeResolverTest
+{
+    private TypeResolver typeResolver;
+    
+    @Mock
+    private ClassLibrary classLibrary;
+
+    @Before 
+    public void initMocks() {
+        MockitoAnnotations.initMocks(this);
+    }
+    
+    @Test
+    public void testResolveTypeInnerClass() throws Exception {
+        when( classLibrary.hasClassReference( "p.X$DogFood" ) ).thenReturn( true );
+        
+        typeResolver = TypeResolver.byClassName( "p.X", classLibrary, Collections.<String>emptyList() );
+        
+        assertEquals("p.X$DogFood", typeResolver.resolveType("DogFood"));
+        assertEquals(null, typeResolver.resolveType("Food"));
+    }
+    
+    @Test
+    public void testResolving()
+        throws Exception
+    {
+        when( classLibrary.hasClassReference( "foo.Bar" ) ).thenReturn( true );
+        
+        typeResolver = TypeResolver.byPackageName( null, classLibrary, Collections.singletonList( "foo.*" )  );
+        
+        assertEquals( "foo.Bar", typeResolver.resolveType( "Bar" ) );
+        assertEquals( "foo.Bar", typeResolver.resolveType( "foo.Bar" ) );
+    }
+    
+    @Test
+    public void testResolveJavaPrimitive() throws Exception {
+        List<String> imports = new ArrayList<String>();
+        imports.add("bogus.int");
+        imports.add("bogus.double");
+        String[] primitives = new String[]{
+            "boolean", "byte", "char", "double",
+            "float", "int", "long", "short", "void"
+        };
+        typeResolver = TypeResolver.byPackageName( null, classLibrary, imports );
+        for (int i = 0; i < primitives.length; i++) {
+            assertEquals(primitives[i], typeResolver.resolveType(primitives[i]));
+        }
+    }
+
+    @Test
+    public void testDontResolveMissingClasses() throws Exception {
+        typeResolver = TypeResolver.byPackageName( null, classLibrary, Collections.<String>emptyList() );
+        assertEquals(null, typeResolver.resolveType("not.Found"));
+    }
+
+    @Test
+    public void testResolveFullyQualifiedName() throws Exception
+    {
+        typeResolver = TypeResolver.byPackageName( null, classLibrary, Collections.<String>emptyList() );
+        when( classLibrary.hasClassReference( "open.Bar" ) ).thenReturn( true );
+        assertEquals( "open.Bar", typeResolver.resolveType( "open.Bar" ) );
+    }
+    
+    @Test
+    public void testResolveFullyQualifiedImport() throws Exception {
+        typeResolver = TypeResolver.byPackageName( null, classLibrary, Collections.singletonList( "foo.Bar" ) );
+        when( classLibrary.hasClassReference( "foo.Bar" ) ).thenReturn( true );
+        assertEquals( "foo.Bar", typeResolver.resolveType( "Bar" ) );
+    }
+
+    @Test
+    public void testResolveChooseFirstMatchingImport() throws Exception {
+        List<String> imports = new ArrayList<String>();
+        imports.add( "bogus.package.MyType" );
+        imports.add( "com.thoughtworks.qdox.model.Type" );
+        imports.add( "another.package.Type" );
+        typeResolver = TypeResolver.byPackageName( null, classLibrary, imports );
+        when( classLibrary.hasClassReference( "bogus.package.MyType" ) ).thenReturn( true );
+        when( classLibrary.hasClassReference( "com.thoughtworks.qdox.model.Type" ) ).thenReturn( true );
+        when( classLibrary.hasClassReference( "another.package.Type" ) ).thenReturn( true );
+        assertEquals( "com.thoughtworks.qdox.model.Type", typeResolver.resolveType( "Type" ) );
+    }
+
+    @Test
+    public void testResolveSamePackage() throws Exception {
+        typeResolver = TypeResolver.byPackageName( "foo", classLibrary, Collections.<String>emptyList() );
+        when( classLibrary.hasClassReference( "foo.Bar" ) ).thenReturn( true );
+        assertEquals("foo.Bar", typeResolver.resolveType("Bar"));
+    }
+
+    @Test
+    public void testResolveFullyQualifiedTrumpsSamePackage() throws Exception {
+        typeResolver = TypeResolver.byPackageName( "foo", classLibrary, Collections.<String>emptyList() );
+        when( classLibrary.hasClassReference( "foo.Bar" ) ).thenReturn( true );
+        when( classLibrary.hasClassReference( "open.Bar" ) ).thenReturn( true );
+        assertEquals("open.Bar", typeResolver.resolveType("open.Bar"));
+    }
+
+    @Test
+    public void testResolveFullyQualifiedTrumpsWildCard() throws Exception {
+        List<String> imports = new ArrayList<String>();
+        imports.add("foo.*");
+        imports.add("bar.Bar");
+        typeResolver = TypeResolver.byPackageName( null, classLibrary, imports );
+        when( classLibrary.hasClassReference( "foo.Bar" ) ).thenReturn( true );
+        when( classLibrary.hasClassReference( "bar.Bar" ) ).thenReturn( true );
+        assertEquals("bar.Bar", typeResolver.resolveType("Bar"));
+    }
+
+    @Test
+    public void testResolveWildcard() throws Exception {
+        typeResolver = TypeResolver.byPackageName( null, classLibrary, Collections.singletonList("foo.*") );
+        when( classLibrary.hasClassReference( "foo.Bar" ) ).thenReturn( true );
+        assertEquals("foo.Bar", typeResolver.resolveType("Bar"));
+    }
+
+    @Test
+    public void testResolveJavaLangClass() throws Exception {
+        typeResolver = TypeResolver.byPackageName( null, classLibrary, Collections.<String>emptyList() );
+        when( classLibrary.hasClassReference( "java.lang.System" ) ).thenReturn( true );
+        assertEquals("java.lang.System", typeResolver.resolveType("System"));
+    }
+
+    @Test
+    public void testResolveSamePackageTrumpsWildcard() throws Exception {
+        List<String> imports = new ArrayList<String>();
+        imports.add("com.thoughtworks.qdox.model.Type");
+        imports.add("foo.*");
+        typeResolver = TypeResolver.byPackageName( "com.thoughtworks.qdox.model", classLibrary, imports );
+        when( classLibrary.hasClassReference( "com.thoughtworks.qdox.model.Type" ) ).thenReturn( true );
+        when( classLibrary.hasClassReference( "foo.Type" ) ).thenReturn( true );
+        assertEquals("com.thoughtworks.qdox.model.Type", typeResolver.resolveType("Type"));
+    }
+
+    @Test
+    public void testResolveFullyQualifiedInnerClass() throws Exception {
+        typeResolver = TypeResolver.byPackageName( "foo", classLibrary, Collections.<String>emptyList() );
+        when( classLibrary.hasClassReference( "foo.Bar$Fnord" ) ).thenReturn( true );
+        assertEquals("foo.Bar$Fnord", typeResolver.resolveType("foo.Bar.Fnord"));
+    }
+
+    @Test
+    public void testResolvePartiallySpecifiedInnerClass() throws Exception {
+        typeResolver = TypeResolver.byPackageName( "foo", classLibrary, Collections.singletonList("java.util.*") );
+        when( classLibrary.hasClassReference( "foo.Bar$Fnord" ) ).thenReturn( true );
+        when( classLibrary.hasClassReference( "java.util.Map$Entry" ) ).thenReturn( true );
+        assertEquals("foo.Bar$Fnord", typeResolver.resolveType("Bar.Fnord"));
+        assertEquals("java.util.Map$Entry", typeResolver.resolveType("Map.Entry"));
+    }
+}
diff --git a/src/test/java/com/thoughtworks/qdox/writer/impl/DefaultModelWriterTest.java b/src/test/java/com/thoughtworks/qdox/writer/impl/DefaultModelWriterTest.java
index 1b62a0a..bacc7bf 100644
--- a/src/test/java/com/thoughtworks/qdox/writer/impl/DefaultModelWriterTest.java
+++ b/src/test/java/com/thoughtworks/qdox/writer/impl/DefaultModelWriterTest.java
@@ -5,6 +5,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
@@ -19,6 +20,14 @@ import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaField;
 import com.thoughtworks.qdox.model.JavaInitializer;
 import com.thoughtworks.qdox.model.JavaMethod;
+import com.thoughtworks.qdox.model.JavaModule;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaExports;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaOpens;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaProvides;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaRequires;
+import com.thoughtworks.qdox.model.JavaModuleDescriptor.JavaUses;
+import com.thoughtworks.qdox.model.JavaPackage;
 import com.thoughtworks.qdox.model.JavaParameter;
 import com.thoughtworks.qdox.model.JavaType;
 import com.thoughtworks.qdox.model.expression.Expression;
@@ -391,5 +400,146 @@ public class DefaultModelWriterTest {
         String expected = "@Anno\n";
         assertEquals( expected, modelWriter.toString() );
     }
+    
+    @Test
+    public void testModuleDescriptor()
+    {
+        JavaModuleDescriptor descriptor = mock(JavaModuleDescriptor.class);
+        when(descriptor.getName()).thenReturn( "M.N" );
+        
+        modelWriter.writeModuleDescriptor( descriptor );
+        
+        String expected = "module M.N {\n\n}\n";
+        assertEquals( expected, modelWriter.toString() );
+    }
 
+    @Test
+    public void testOpenModuleDescriptor()
+    {
+        JavaModuleDescriptor descriptor = mock(JavaModuleDescriptor.class);
+        when(descriptor.getName()).thenReturn( "M.N" );
+        when(descriptor.isOpen()).thenReturn( true );
+        
+        modelWriter.writeModuleDescriptor( descriptor );
+        
+        String expected = "open module M.N {\n\n}\n";
+        assertEquals( expected, modelWriter.toString() );
+    }
+
+    @Test
+    public void testModuleRequires()
+    {
+        JavaRequires requires1 = mock( JavaRequires.class );
+        JavaModule moduleAB = mock(JavaModule.class);
+        when( moduleAB.getName() ).thenReturn( "A.B" );
+        when( requires1.getModule() ).thenReturn( moduleAB );
+        when( requires1.getModifiers() ).thenReturn( Collections.<String>emptyList() );
+        modelWriter.writeModuleRequires( requires1 );
+        assertEquals( "requires A.B;\n", modelWriter.toString() );
+
+        modelWriter = new DefaultModelWriter();
+        JavaRequires requires2 = mock( JavaRequires.class );
+        JavaModule moduleCD = mock(JavaModule.class);
+        when( moduleCD.getName() ).thenReturn( "C.D" );
+        when( requires2.getModule() ).thenReturn( moduleCD);
+        when( requires2.getModifiers() ).thenReturn( Collections.singleton( "public" ) );
+        modelWriter.writeModuleRequires( requires2 );
+        assertEquals( "requires public C.D;\n", modelWriter.toString() );
+        
+        modelWriter = new DefaultModelWriter();
+        JavaRequires requires3 = mock( JavaRequires.class );
+        JavaModule moduleEF = mock(JavaModule.class);
+        when( moduleEF.getName() ).thenReturn( "E.F" );
+        when( requires3.getModule() ).thenReturn( moduleEF );
+        when( requires3.getModifiers() ).thenReturn( Collections.singleton( "static" ) );
+        modelWriter.writeModuleRequires( requires3 );
+        assertEquals( "requires static E.F;\n", modelWriter.toString() );
+        
+        modelWriter = new DefaultModelWriter();
+        JavaRequires requires4 = mock( JavaRequires.class );
+        JavaModule moduleGH = mock(JavaModule.class);
+        when( moduleGH.getName() ).thenReturn( "G.H" );
+        when( requires4.getModule() ).thenReturn( moduleGH );
+        when( requires4.getModifiers() ).thenReturn( Arrays.asList( "public", "static" ) );
+        modelWriter.writeModuleRequires( requires4 );
+        assertEquals( "requires public static G.H;\n", modelWriter.toString() );
+    }
+    
+    @Test
+    public void testModuleExports()
+    {
+        JavaExports exports1 = mock( JavaExports.class );
+        JavaPackage sourcePQ = mock(JavaPackage.class);
+        when(sourcePQ.getName()).thenReturn( "P.Q" );
+        when( exports1.getSource() ).thenReturn( sourcePQ );
+        modelWriter.writeModuleExports( exports1 );
+        assertEquals( "exports P.Q;\n", modelWriter.toString() );
+
+        modelWriter = new DefaultModelWriter();
+        JavaExports exports2 = mock( JavaExports.class );
+        JavaPackage sourceRS = mock(JavaPackage.class);
+        when(sourceRS.getName()).thenReturn( "R.S" );
+        when( exports2.getSource() ).thenReturn( sourceRS );
+        
+        JavaModule moduleT1U1 = mock( JavaModule.class );
+        when( moduleT1U1.getName() ).thenReturn( "T1.U1" );
+        JavaModule moduleT2U2 = mock( JavaModule.class );
+        when( moduleT2U2.getName() ).thenReturn( "T2.U2" );
+        when(exports2.getTargets()).thenReturn( Arrays.asList( moduleT1U1, moduleT2U2 ) );
+        modelWriter.writeModuleExports( exports2 );
+        assertEquals( "exports R.S to T1.U1, T2.U2;\n", modelWriter.toString() );
+    }
+    
+    @Test
+    public void testModuleOpens()
+    {
+        modelWriter = new DefaultModelWriter();
+        JavaOpens opens1 = mock( JavaOpens.class );
+        JavaPackage source1 = mock(JavaPackage.class);
+        when(source1.getName()).thenReturn( "P.Q" );
+        when( opens1.getSource() ).thenReturn( source1 );
+        modelWriter.writeModuleOpens( opens1 );
+        assertEquals( "opens P.Q;\n", modelWriter.toString() );
+
+        modelWriter = new DefaultModelWriter();
+        JavaOpens opens2 = mock( JavaOpens.class );
+        JavaPackage source2 = mock(JavaPackage.class);
+        when(source2.getName()).thenReturn( "R.S" );
+        when( opens2.getSource() ).thenReturn( source2 );
+        
+        JavaModule moduleT1U1 = mock( JavaModule.class );
+        when( moduleT1U1.getName() ).thenReturn( "T1.U1" );
+        JavaModule moduleT2U2 = mock( JavaModule.class );
+        when( moduleT2U2.getName() ).thenReturn( "T2.U2" );
+        when( opens2.getTargets()).thenReturn( Arrays.asList( moduleT1U1, moduleT2U2 ) );
+        modelWriter.writeModuleOpens( opens2 );
+        assertEquals( "opens R.S to T1.U1, T2.U2;\n", modelWriter.toString() );
+    }
+    
+    @Test
+    public void testModuleProvides()
+    {
+        JavaProvides provides = mock( JavaProvides.class );
+        JavaClass service = mock( JavaClass.class );
+        when( service.getName() ).thenReturn( "X.Y" );
+        JavaClass providerZ1Z2 = mock( JavaClass.class );
+        when( providerZ1Z2.getName() ).thenReturn( "Z1.Z2" );
+        JavaClass providerZ3Z4 = mock( JavaClass.class );
+        when( providerZ3Z4.getName() ).thenReturn( "Z3.Z4" );
+        when( provides.getService() ).thenReturn( service );
+        when( provides.getProviders() ).thenReturn( Arrays.asList( providerZ1Z2, providerZ3Z4 ) );
+        modelWriter.writeModuleProvides( provides );
+        assertEquals( "provides X.Y with Z1.Z2, Z3.Z4;\n", modelWriter.toString() );
+    }
+
+    @Test
+    public void testModuleUses()
+    {
+        JavaUses uses = mock( JavaUses.class );
+        JavaClass service = mock( JavaClass.class );
+        when( service.getName() ).thenReturn( "V.W" );
+        when( uses.getService() ).thenReturn( service );
+        modelWriter.writeModuleUses( uses );
+        assertEquals( "uses V.W;\n", modelWriter.toString() );
+    }
 }
diff --git a/src/test/resources/com/thoughtworks/qdox/testdata/module-info.java b/src/test/resources/com/thoughtworks/qdox/testdata/module-info.java
new file mode 100644
index 0000000..9ed2357
--- /dev/null
+++ b/src/test/resources/com/thoughtworks/qdox/testdata/module-info.java
@@ -0,0 +1,4 @@
+module qdoxtest
+{
+  exports com.thoughtworks.qdox;
+}
\ No newline at end of file
diff --git a/src/test/resources/jigsaw/example1/module-info.java b/src/test/resources/jigsaw/example1/module-info.java
new file mode 100644
index 0000000..e84479a
--- /dev/null
+++ b/src/test/resources/jigsaw/example1/module-info.java
@@ -0,0 +1,16 @@
+ at Bar
+module M.N {
+  requires A.B;
+  requires transitive C.D;
+  requires static E.F;
+  requires transitive static G.H;
+
+  exports P.Q;
+  exports R.S to T1.U1, T2.U2;
+
+  opens P.Q;
+  opens R.S to T1.U1, T2.U2;
+
+  uses V.W;
+  provides X.Y with Z1.Z2, Z3.Z4;
+}
\ No newline at end of file
diff --git a/src/test/resources/jigsaw/example2/module-info.java b/src/test/resources/jigsaw/example2/module-info.java
new file mode 100644
index 0000000..1ee2b2d
--- /dev/null
+++ b/src/test/resources/jigsaw/example2/module-info.java
@@ -0,0 +1,13 @@
+ at Foo(1) @Foo(2) @Bar
+open module M.N {
+  requires A.B;
+  requires transitive C.D;
+  requires static E.F;
+  requires transitive static G.H;
+
+  exports P.Q;
+  exports R.S to T1.U1, T2.U2;
+
+  uses V.W;
+  provides X.Y with Z1.Z2, Z3.Z4;
+}
\ No newline at end of file

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/qdox2.git



More information about the pkg-java-commits mailing list